コード例 #1
0
ファイル: brw_sf.c プロジェクト: chemecse/mesa
/* Calculate interpolants for triangle and line rasterization.
 */
void
brw_upload_sf_prog(struct brw_context *brw)
{
   struct gl_context *ctx = &brw->ctx;
   struct brw_sf_prog_key key;

   if (!brw_state_dirty(brw,
                        _NEW_BUFFERS |
                        _NEW_HINT |
                        _NEW_LIGHT |
                        _NEW_POINT |
                        _NEW_POLYGON |
                        _NEW_PROGRAM |
                        _NEW_TRANSFORM,
                        BRW_NEW_BLORP |
                        BRW_NEW_FS_PROG_DATA |
                        BRW_NEW_REDUCED_PRIMITIVE |
                        BRW_NEW_VUE_MAP_GEOM_OUT))
      return;

   /* _NEW_BUFFERS */
   bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);

   memset(&key, 0, sizeof(key));

   /* Populate the key, noting state dependencies:
    */
   /* BRW_NEW_VUE_MAP_GEOM_OUT */
   key.attrs = brw->vue_map_geom_out.slots_valid;

   /* BRW_NEW_REDUCED_PRIMITIVE */
   switch (brw->reduced_primitive) {
   case GL_TRIANGLES:
      /* NOTE: We just use the edgeflag attribute as an indicator that
       * unfilled triangles are active.  We don't actually do the
       * edgeflag testing here, it is already done in the clip
       * program.
       */
      if (key.attrs & BITFIELD64_BIT(VARYING_SLOT_EDGE))
	 key.primitive = BRW_SF_PRIM_UNFILLED_TRIS;
      else
	 key.primitive = BRW_SF_PRIM_TRIANGLES;
      break;
   case GL_LINES:
      key.primitive = BRW_SF_PRIM_LINES;
      break;
   case GL_POINTS:
      key.primitive = BRW_SF_PRIM_POINTS;
      break;
   }

   /* _NEW_TRANSFORM */
   key.userclip_active = (ctx->Transform.ClipPlanesEnabled != 0);

   /* _NEW_POINT */
   key.do_point_sprite = ctx->Point.PointSprite;
   if (key.do_point_sprite) {
      key.point_sprite_coord_replace = ctx->Point.CoordReplace & 0xff;
   }
   if (brw->programs[MESA_SHADER_FRAGMENT]->info.inputs_read &
       BITFIELD64_BIT(VARYING_SLOT_PNTC)) {
      key.do_point_coord = 1;
   }

   /*
    * Window coordinates in a FBO are inverted, which means point
    * sprite origin must be inverted, too.
    */
   if ((ctx->Point.SpriteOrigin == GL_LOWER_LEFT) != render_to_fbo)
      key.sprite_origin_lower_left = true;

   /* BRW_NEW_FS_PROG_DATA */
   const struct brw_wm_prog_data *wm_prog_data =
      brw_wm_prog_data(brw->wm.base.prog_data);
   if (wm_prog_data) {
      key.contains_flat_varying = wm_prog_data->contains_flat_varying;

      STATIC_ASSERT(sizeof(key.interp_mode) ==
                    sizeof(wm_prog_data->interp_mode));
      memcpy(key.interp_mode, wm_prog_data->interp_mode,
             sizeof(key.interp_mode));
   }

   /* _NEW_LIGHT | _NEW_PROGRAM */
   key.do_twoside_color = _mesa_vertex_program_two_side_enabled(ctx);

   /* _NEW_POLYGON */
   if (key.do_twoside_color) {
      /* If we're rendering to a FBO, we have to invert the polygon
       * face orientation, just as we invert the viewport in
       * sf_unit_create_from_key().
       */
      key.frontface_ccw = brw->polygon_front_bit == render_to_fbo;
   }

   if (!brw_search_cache(&brw->cache, BRW_CACHE_SF_PROG,
			 &key, sizeof(key),
			 &brw->sf.prog_offset, &brw->sf.prog_data)) {
      compile_sf_prog( brw, &key );
   }
}
コード例 #2
0
ファイル: st_atom_rasterizer.c プロジェクト: ndesh26/Mesa
void st_update_rasterizer( struct st_context *st )
{
   struct gl_context *ctx = st->ctx;
   struct pipe_rasterizer_state *raster = &st->state.rasterizer;
   const struct gl_program *vertProg = ctx->VertexProgram._Current;
   const struct gl_program *fragProg = ctx->FragmentProgram._Current;

   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->state.fb_orientation == 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 = _mesa_vertex_program_two_side_enabled(ctx);

   /*_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->state.fb_orientation == 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.
       */
      raster->sprite_coord_enable = ctx->Point.CoordReplace &
         ((1u << MAX_TEXTURE_COORD_UNITS) - 1);
      if (!st->needs_texcoord_semantic &&
          fragProg->info.inputs_read & 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->Id == 0) {
         if (vertProg->info.outputs_written &
             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;
         else if (ctx->TessEvalProgram._Current)
            last = ctx->TessEvalProgram._Current;
         else if (ctx->VertexProgram._Current)
            last = ctx->VertexProgram._Current;
         if (last)
            raster->point_size_per_vertex =
               !!(last->info.outputs_written &
                  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 &&
         raster->multisample &&
         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->state.fb_orientation == 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);
}