/**
 * Prepare/validate middle part of the vertex pipeline.
 * NOTE: if you change this function, also look at the LLVM
 * function llvm_middle_end_prepare() for similar changes.
 */
static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
                                    unsigned prim,
				    unsigned opt,
                                    unsigned *max_vertices )
{
   struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
   struct draw_context *draw = fpme->draw;
   struct draw_vertex_shader *vs = draw->vs.vertex_shader;
   struct draw_geometry_shader *gs = draw->gs.geometry_shader;
   unsigned i;
   unsigned instance_id_index = ~0;

   unsigned gs_out_prim = (gs ? gs->output_primitive : prim);

   /* Add one to num_outputs because the pipeline occasionally tags on
    * an additional texcoord, eg for AA lines.
    */
   unsigned nr = MAX2( vs->info.num_inputs,
		       vs->info.num_outputs + 1 );

   if (gs) {
      nr = MAX2(nr, gs->info.num_outputs + 1);
   }

   /* Scan for instanceID system value.
    */
   for (i = 0; i < vs->info.num_inputs; i++) {
      if (vs->info.input_semantic_name[i] == TGSI_SEMANTIC_INSTANCEID) {
         instance_id_index = i;
         break;
      }
   }

   fpme->input_prim = prim;
   fpme->opt = opt;

   /* Always leave room for the vertex header whether we need it or
    * not.  It's hard to get rid of it in particular because of the
    * viewport code in draw_pt_post_vs.c.  
    */
   fpme->vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float);

   

   draw_pt_fetch_prepare( fpme->fetch, 
                          vs->info.num_inputs,
                          fpme->vertex_size,
                          instance_id_index );
   /* XXX: it's not really gl rasterization rules we care about here,
    * but gl vs dx9 clip spaces.
    */
   draw_pt_post_vs_prepare( fpme->post_vs,
			    draw->clip_xy,
			    draw->clip_z,
			    draw->clip_user,
                            draw->guard_band_xy,
			    draw->identity_viewport,
			    (boolean)draw->rasterizer->gl_rasterization_rules,
			    (draw->vs.edgeflag_output ? TRUE : FALSE) );

   draw_pt_so_emit_prepare( fpme->so_emit, FALSE );

   if (!(opt & PT_PIPELINE)) {
      draw_pt_emit_prepare( fpme->emit,
			    gs_out_prim,
                            max_vertices );

      *max_vertices = MAX2( *max_vertices, 4096 );
   }
   else {
      /* limit max fetches by limiting max_vertices */
      *max_vertices = 4096;
   }

   /* No need to prepare the shader.
    */
   vs->prepare(vs, draw);
}
static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
                                    unsigned prim,
				    unsigned opt,
                                    unsigned *max_vertices )
{
   struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
   struct draw_context *draw = fpme->draw;
   struct draw_vertex_shader *vs = draw->vs.vertex_shader;
   unsigned i;
   unsigned instance_id_index = ~0;

   /* Add one to num_outputs because the pipeline occasionally tags on
    * an additional texcoord, eg for AA lines.
    */
   unsigned nr = MAX2( vs->info.num_inputs,
		       vs->info.num_outputs + 1 );

   /* Scan for instanceID system value.
    */
   for (i = 0; i < vs->info.num_inputs; i++) {
      if (vs->info.input_semantic_name[i] == TGSI_SEMANTIC_INSTANCEID) {
         instance_id_index = i;
         break;
      }
   }

   fpme->prim = prim;
   fpme->opt = opt;

   /* Always leave room for the vertex header whether we need it or
    * not.  It's hard to get rid of it in particular because of the
    * viewport code in draw_pt_post_vs.c.  
    */
   fpme->vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float);

   

   draw_pt_fetch_prepare( fpme->fetch, 
                          vs->info.num_inputs,
                          fpme->vertex_size,
                          instance_id_index );
   /* XXX: it's not really gl rasterization rules we care about here,
    * but gl vs dx9 clip spaces.
    */
   draw_pt_post_vs_prepare( fpme->post_vs,
			    (boolean)draw->bypass_clipping,
			    (boolean)draw->identity_viewport,
			    (boolean)draw->rasterizer->gl_rasterization_rules,
			    (draw->vs.edgeflag_output ? true : false) );    

   if (!(opt & PT_PIPELINE)) {
      draw_pt_emit_prepare( fpme->emit, 
			    prim,
                            max_vertices );

      *max_vertices = MAX2( *max_vertices,
                            DRAW_PIPE_MAX_VERTICES );
   }
   else {
      *max_vertices = DRAW_PIPE_MAX_VERTICES; 
   }

   /* return even number */
   *max_vertices = *max_vertices & ~1;

   /* No need to prepare the shader.
    */
   vs->prepare(vs, draw);
}