Пример #1
0
/* Calculates the key for triangle-mode clipping.  Non-triangle
 * clipping keys use much less information and are computed on the
 * fly.
 */
static void
calculate_clip_key_rast( const struct brw_context *brw,
                         const struct pipe_rasterizer_state *templ,
                         const struct brw_rasterizer_state *rast,
                         struct brw_clip_prog_key *key)
{
    memset(key, 0, sizeof *key);

    if (brw->chipset.is_igdng)
        key->clip_mode = BRW_CLIPMODE_KERNEL_CLIP;
    else
        key->clip_mode = BRW_CLIPMODE_NORMAL;

    key->do_flat_shading = templ->flatshade;

    if (templ->cull_mode == PIPE_WINDING_BOTH) {
        key->clip_mode = BRW_CLIPMODE_REJECT_ALL;
        return;
    }

    key->fill_ccw = CLIP_CULL;
    key->fill_cw = CLIP_CULL;

    if (!(templ->cull_mode & PIPE_WINDING_CCW)) {
        key->fill_ccw = translate_fill(templ->fill_ccw);
    }

    if (!(templ->cull_mode & PIPE_WINDING_CW)) {
        key->fill_cw = translate_fill(templ->fill_cw);
    }

    if (key->fill_cw == CLIP_LINE ||
            key->fill_ccw == CLIP_LINE ||
            key->fill_cw == CLIP_POINT ||
            key->fill_ccw == CLIP_POINT) {
        key->do_unfilled = 1;
        key->clip_mode = BRW_CLIPMODE_CLIP_NON_REJECTED;
    }

    key->offset_ccw = templ->offset_ccw;
    key->offset_cw = templ->offset_cw;

    if (templ->light_twoside && key->fill_cw != CLIP_CULL)
        key->copy_bfc_cw = 1;

    if (templ->light_twoside && key->fill_ccw != CLIP_CULL)
        key->copy_bfc_ccw = 1;
}
Пример #2
0
static void update_raster_state( struct st_context *st )
{
   struct gl_context *ctx = st->ctx;
   struct pipe_rasterizer_state *raster = &st->state.rasterizer;
   const struct gl_vertex_program *vertProg = ctx->VertexProgram._Current;
   const struct gl_fragment_program *fragProg = ctx->FragmentProgram._Current;
   uint i;

   memset(raster, 0, sizeof(*raster));

   /* _NEW_POLYGON, _NEW_BUFFERS
    */
   {
      raster->front_ccw = (ctx->Polygon.FrontFace == GL_CCW);

      /*
       * Gallium's surfaces are Y=0=TOP orientation.  OpenGL is the
       * opposite.  Window system surfaces are Y=0=TOP.  Mesa's FBOs
       * must match OpenGL conventions so FBOs use Y=0=BOTTOM.  In that
       * case, we must invert Y and flip the notion of front vs. back.
       */
      if (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM) {
         /* Drawing to an FBO.  The viewport will be inverted. */
         raster->front_ccw ^= 1;
      }
   }

   /* _NEW_LIGHT
    */
   if (ctx->Light.ShadeModel == GL_FLAT)
      raster->flatshade = 1;

   if (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION_EXT)
      raster->flatshade_first = 1;

   /* _NEW_LIGHT | _NEW_PROGRAM */
   raster->light_twoside = ctx->VertexProgram._TwoSideEnabled;

   /*_NEW_LIGHT | _NEW_BUFFERS */
   raster->clamp_vertex_color = !st->clamp_vert_color_in_shader &&
                                ctx->Light._ClampVertexColor;

   /* _NEW_POLYGON
    */
   if (ctx->Polygon.CullFlag) {
      switch (ctx->Polygon.CullFaceMode) {
      case GL_FRONT:
	 raster->cull_face = PIPE_FACE_FRONT;
         break;
      case GL_BACK:
	 raster->cull_face = PIPE_FACE_BACK;
         break;
      case GL_FRONT_AND_BACK:
	 raster->cull_face = PIPE_FACE_FRONT_AND_BACK;
         break;
      }
   }
   else {
      raster->cull_face = PIPE_FACE_NONE;
   }

   /* _NEW_POLYGON
    */
   {
      raster->fill_front = translate_fill( ctx->Polygon.FrontMode );
      raster->fill_back = translate_fill( ctx->Polygon.BackMode );

      /* Simplify when culling is active:
       */
      if (raster->cull_face & PIPE_FACE_FRONT) {
	 raster->fill_front = raster->fill_back;
      }
      
      if (raster->cull_face & PIPE_FACE_BACK) {
	 raster->fill_back = raster->fill_front;
      }
   }

   /* _NEW_POLYGON 
    */
   if (ctx->Polygon.OffsetUnits != 0.0 ||
       ctx->Polygon.OffsetFactor != 0.0) {
      raster->offset_point = ctx->Polygon.OffsetPoint;
      raster->offset_line = ctx->Polygon.OffsetLine;
      raster->offset_tri = ctx->Polygon.OffsetFill;
   }

   if (ctx->Polygon.OffsetPoint ||
       ctx->Polygon.OffsetLine ||
       ctx->Polygon.OffsetFill) {
      raster->offset_units = ctx->Polygon.OffsetUnits;
      raster->offset_scale = ctx->Polygon.OffsetFactor;
   }

   if (ctx->Polygon.SmoothFlag)
      raster->poly_smooth = 1;

   if (ctx->Polygon.StippleFlag)
      raster->poly_stipple_enable = 1;

   /* _NEW_POINT
    */
   raster->point_size = ctx->Point.Size;

   if (!ctx->Point.PointSprite && ctx->Point.SmoothFlag)
      raster->point_smooth = 1;

   /* _NEW_POINT | _NEW_PROGRAM
    */
   if (ctx->Point.PointSprite) {
      /* origin */
      if ((ctx->Point.SpriteOrigin == GL_UPPER_LEFT) ^
          (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM))
         raster->sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT;
      else 
         raster->sprite_coord_mode = PIPE_SPRITE_COORD_LOWER_LEFT;

      /* Coord replacement flags.  If bit 'k' is set that means
       * that we need to replace GENERIC[k] attrib with an automatically
       * computed texture coord.
       */
      for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
         if (ctx->Point.CoordReplace[i]) {
            raster->sprite_coord_enable |= 1 << i;
         }
      }
      if (fragProg->Base.InputsRead & FRAG_BIT_PNTC) {
         raster->sprite_coord_enable |=
            1 << (FRAG_ATTRIB_PNTC - FRAG_ATTRIB_TEX0);
      }

      raster->point_quad_rasterization = 1;
   }

   /* ST_NEW_VERTEX_PROGRAM
    */
   if (vertProg) {
      if (vertProg->Base.Id == 0) {
         if (vertProg->Base.OutputsWritten & BITFIELD64_BIT(VERT_RESULT_PSIZ)) {
            /* generated program which emits point size */
            raster->point_size_per_vertex = TRUE;
         }
      }
      else if (ctx->VertexProgram.PointSizeEnabled) {
         /* user-defined program and GL_VERTEX_PROGRAM_POINT_SIZE set */
         raster->point_size_per_vertex = ctx->VertexProgram.PointSizeEnabled;
      }
   }
   if (!raster->point_size_per_vertex) {
      /* clamp size now */
      raster->point_size = CLAMP(ctx->Point.Size,
                                 ctx->Point.MinSize,
                                 ctx->Point.MaxSize);
   }

   /* _NEW_LINE
    */
   raster->line_smooth = ctx->Line.SmoothFlag;
   if (ctx->Line.SmoothFlag) {
      raster->line_width = CLAMP(ctx->Line.Width,
                                ctx->Const.MinLineWidthAA,
                                ctx->Const.MaxLineWidthAA);
   }
   else {
      raster->line_width = CLAMP(ctx->Line.Width,
                                ctx->Const.MinLineWidth,
                                ctx->Const.MaxLineWidth);
   }

   raster->line_stipple_enable = ctx->Line.StippleFlag;
   raster->line_stipple_pattern = ctx->Line.StipplePattern;
   /* GL stipple factor is in [1,256], remap to [0, 255] here */
   raster->line_stipple_factor = ctx->Line.StippleFactor - 1;

   /* _NEW_MULTISAMPLE */
   if (ctx->Multisample._Enabled || st->force_msaa)
      raster->multisample = 1;

   /* _NEW_SCISSOR */
   if (ctx->Scissor.Enabled)
      raster->scissor = 1;

   /* _NEW_FRAG_CLAMP */
   raster->clamp_fragment_color = !st->clamp_frag_color_in_shader &&
                                  ctx->Color._ClampFragmentColor;
   raster->gl_rasterization_rules = 1;

   /* _NEW_RASTERIZER_DISCARD */
   raster->rasterizer_discard = ctx->RasterDiscard;

   /* _NEW_TRANSFORM */
   raster->depth_clip = ctx->Transform.DepthClamp == GL_FALSE;
   raster->clip_plane_enable = ctx->Transform.ClipPlanesEnabled;

   cso_set_rasterizer(st->cso_context, raster);
}
Пример #3
0
static void update_raster_state( struct st_context *st )
{
   struct gl_context *ctx = st->ctx;
   struct pipe_rasterizer_state *raster = &st->state.rasterizer;
   const struct gl_vertex_program *vertProg = ctx->VertexProgram._Current;
   const struct gl_fragment_program *fragProg = ctx->FragmentProgram._Current;
   uint i;

   memset(raster, 0, sizeof(*raster));

   /* _NEW_POLYGON, _NEW_BUFFERS
    */
   {
      raster->front_ccw = (ctx->Polygon.FrontFace == GL_CCW);

      /* _NEW_TRANSFORM */
      if (ctx->Transform.ClipOrigin == GL_UPPER_LEFT) {
         raster->front_ccw ^= 1;
      }

      /*
       * Gallium's surfaces are Y=0=TOP orientation.  OpenGL is the
       * opposite.  Window system surfaces are Y=0=TOP.  Mesa's FBOs
       * must match OpenGL conventions so FBOs use Y=0=BOTTOM.  In that
       * case, we must invert Y and flip the notion of front vs. back.
       */
      if (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM) {
         /* Drawing to an FBO.  The viewport will be inverted. */
         raster->front_ccw ^= 1;
      }
   }

   /* _NEW_LIGHT
    */
   raster->flatshade = ctx->Light.ShadeModel == GL_FLAT;
      
   raster->flatshade_first = ctx->Light.ProvokingVertex ==
                             GL_FIRST_VERTEX_CONVENTION_EXT;

   /* _NEW_LIGHT | _NEW_PROGRAM */
   raster->light_twoside = ctx->VertexProgram._TwoSideEnabled;

   /*_NEW_LIGHT | _NEW_BUFFERS */
   raster->clamp_vertex_color = !st->clamp_vert_color_in_shader &&
                                ctx->Light._ClampVertexColor;

   /* _NEW_POLYGON
    */
   if (ctx->Polygon.CullFlag) {
      switch (ctx->Polygon.CullFaceMode) {
      case GL_FRONT:
	 raster->cull_face = PIPE_FACE_FRONT;
         break;
      case GL_BACK:
	 raster->cull_face = PIPE_FACE_BACK;
         break;
      case GL_FRONT_AND_BACK:
	 raster->cull_face = PIPE_FACE_FRONT_AND_BACK;
         break;
      }
   }
   else {
      raster->cull_face = PIPE_FACE_NONE;
   }

   /* _NEW_POLYGON
    */
   {
      if (ST_DEBUG & DEBUG_WIREFRAME) {
         raster->fill_front = PIPE_POLYGON_MODE_LINE;
         raster->fill_back = PIPE_POLYGON_MODE_LINE;
      }
      else {
         raster->fill_front = translate_fill( ctx->Polygon.FrontMode );
         raster->fill_back = translate_fill( ctx->Polygon.BackMode );
      }

      /* Simplify when culling is active:
       */
      if (raster->cull_face & PIPE_FACE_FRONT) {
	 raster->fill_front = raster->fill_back;
      }
      
      if (raster->cull_face & PIPE_FACE_BACK) {
	 raster->fill_back = raster->fill_front;
      }
   }

   /* _NEW_POLYGON 
    */
   if (ctx->Polygon.OffsetPoint ||
       ctx->Polygon.OffsetLine ||
       ctx->Polygon.OffsetFill) {
      raster->offset_point = ctx->Polygon.OffsetPoint;
      raster->offset_line = ctx->Polygon.OffsetLine;
      raster->offset_tri = ctx->Polygon.OffsetFill;
      raster->offset_units = ctx->Polygon.OffsetUnits;
      raster->offset_scale = ctx->Polygon.OffsetFactor;
      raster->offset_clamp = ctx->Polygon.OffsetClamp;
   }

   raster->poly_smooth = ctx->Polygon.SmoothFlag;
   raster->poly_stipple_enable = ctx->Polygon.StippleFlag;

   /* _NEW_POINT
    */
   raster->point_size = ctx->Point.Size;
   raster->point_smooth = !ctx->Point.PointSprite && ctx->Point.SmoothFlag;

   /* _NEW_POINT | _NEW_PROGRAM
    */
   if (ctx->Point.PointSprite) {
      /* origin */
      if ((ctx->Point.SpriteOrigin == GL_UPPER_LEFT) ^
          (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM))
         raster->sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT;
      else 
         raster->sprite_coord_mode = PIPE_SPRITE_COORD_LOWER_LEFT;

      /* Coord replacement flags.  If bit 'k' is set that means
       * that we need to replace GENERIC[k] attrib with an automatically
       * computed texture coord.
       */
      for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
         if (ctx->Point.CoordReplace[i]) {
            raster->sprite_coord_enable |= 1 << i;
         }
      }
      if (!st->needs_texcoord_semantic &&
          fragProg->Base.InputsRead & VARYING_BIT_PNTC) {
         raster->sprite_coord_enable |=
            1 << st_get_generic_varying_index(st, VARYING_SLOT_PNTC);
      }

      raster->point_quad_rasterization = 1;
   }

   /* ST_NEW_VERTEX_PROGRAM
    */
   if (vertProg) {
      if (vertProg->Base.Id == 0) {
         if (vertProg->Base.OutputsWritten & BITFIELD64_BIT(VARYING_SLOT_PSIZ)) {
            /* generated program which emits point size */
            raster->point_size_per_vertex = TRUE;
         }
      }
      else if (ctx->API != API_OPENGLES2) {
         /* PointSizeEnabled is always set in ES2 contexts */
         raster->point_size_per_vertex = ctx->VertexProgram.PointSizeEnabled;
      }
      else {
         /* ST_NEW_TESSEVAL_PROGRAM | ST_NEW_GEOMETRY_PROGRAM */
         /* We have to check the last bound stage and see if it writes psize */
         struct gl_program *last = NULL;
         if (ctx->GeometryProgram._Current)
            last = &ctx->GeometryProgram._Current->Base;
         else if (ctx->TessEvalProgram._Current)
            last = &ctx->TessEvalProgram._Current->Base;
         else if (ctx->VertexProgram._Current)
            last = &ctx->VertexProgram._Current->Base;
         if (last)
            raster->point_size_per_vertex =
               !!(last->OutputsWritten & BITFIELD64_BIT(VARYING_SLOT_PSIZ));
      }
   }
   if (!raster->point_size_per_vertex) {
      /* clamp size now */
      raster->point_size = CLAMP(ctx->Point.Size,
                                 ctx->Point.MinSize,
                                 ctx->Point.MaxSize);
   }

   /* _NEW_LINE
    */
   raster->line_smooth = ctx->Line.SmoothFlag;
   if (ctx->Line.SmoothFlag) {
      raster->line_width = CLAMP(ctx->Line.Width,
                                 ctx->Const.MinLineWidthAA,
                                 ctx->Const.MaxLineWidthAA);
   }
   else {
      raster->line_width = CLAMP(ctx->Line.Width,
                                 ctx->Const.MinLineWidth,
                                 ctx->Const.MaxLineWidth);
   }

   raster->line_stipple_enable = ctx->Line.StippleFlag;
   raster->line_stipple_pattern = ctx->Line.StipplePattern;
   /* GL stipple factor is in [1,256], remap to [0, 255] here */
   raster->line_stipple_factor = ctx->Line.StippleFactor - 1;

   /* _NEW_MULTISAMPLE */
   raster->multisample = _mesa_is_multisample_enabled(ctx);

   /* _NEW_MULTISAMPLE | _NEW_BUFFERS */
   raster->force_persample_interp =
         !st->force_persample_in_shader &&
         _mesa_is_multisample_enabled(ctx) &&
         ctx->Multisample.SampleShading &&
         ctx->Multisample.MinSampleShadingValue *
         _mesa_geometric_samples(ctx->DrawBuffer) > 1;

   /* _NEW_SCISSOR */
   raster->scissor = ctx->Scissor.EnableFlags;

   /* _NEW_FRAG_CLAMP */
   raster->clamp_fragment_color = !st->clamp_frag_color_in_shader &&
                                  ctx->Color._ClampFragmentColor;

   raster->half_pixel_center = 1;
   if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP)
      raster->bottom_edge_rule = 1;
   /* _NEW_TRANSFORM */
   if (ctx->Transform.ClipOrigin == GL_UPPER_LEFT)
      raster->bottom_edge_rule ^= 1;

   /* ST_NEW_RASTERIZER */
   raster->rasterizer_discard = ctx->RasterDiscard;

   if (st->edgeflag_culls_prims) {
      /* All edge flags are FALSE. Cull the affected faces. */
      if (raster->fill_front != PIPE_POLYGON_MODE_FILL)
         raster->cull_face |= PIPE_FACE_FRONT;
      if (raster->fill_back != PIPE_POLYGON_MODE_FILL)
         raster->cull_face |= PIPE_FACE_BACK;
   }

   /* _NEW_TRANSFORM */
   raster->depth_clip = !ctx->Transform.DepthClamp;
   raster->clip_plane_enable = ctx->Transform.ClipPlanesEnabled;
   raster->clip_halfz = (ctx->Transform.ClipDepthMode == GL_ZERO_TO_ONE);

   cso_set_rasterizer(st->cso_context, raster);
}