Ejemplo n.º 1
0
/**
 * The vertex info describes how to convert the post-transformed vertices
 * (simple float[][4]) used by the 'draw' module into vertices for
 * rasterization.
 *
 * This function validates the vertex layout.
 */
static void
compute_vertex_info(struct llvmpipe_context *llvmpipe)
{
   const struct tgsi_shader_info *fsInfo = &llvmpipe->fs->info.base;
   struct vertex_info *vinfo = &llvmpipe->vertex_info;
   int vs_index;
   uint i;

   draw_prepare_shader_outputs(llvmpipe->draw);

   /*
    * Those can't actually be 0 (because pos is always at 0).
    * But use ints anyway to avoid confusion (in vs outputs, they
    * can very well be at pos 0).
    */
   llvmpipe->color_slot[0] = -1;
   llvmpipe->color_slot[1] = -1;
   llvmpipe->bcolor_slot[0] = -1;
   llvmpipe->bcolor_slot[1] = -1;
   llvmpipe->viewport_index_slot = -1;
   llvmpipe->layer_slot = -1;
   llvmpipe->face_slot = -1;
   llvmpipe->psize_slot = -1;

   /*
    * Match FS inputs against VS outputs, emitting the necessary
    * attributes.  Could cache these structs and look them up with a
    * combination of fragment shader, vertex shader ids.
    */

   vinfo->num_attribs = 0;

   vs_index = draw_find_shader_output(llvmpipe->draw,
                                      TGSI_SEMANTIC_POSITION, 0);

   draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);

   for (i = 0; i < fsInfo->num_inputs; i++) {
      /*
       * Search for each input in current vs output:
       */
      vs_index = draw_find_shader_output(llvmpipe->draw,
                                         fsInfo->input_semantic_name[i],
                                         fsInfo->input_semantic_index[i]);

      if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_COLOR &&
          fsInfo->input_semantic_index[i] < 2) {
         int idx = fsInfo->input_semantic_index[i];
         llvmpipe->color_slot[idx] = (int)vinfo->num_attribs;
      }

      if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_FACE) {
         llvmpipe->face_slot = (int)vinfo->num_attribs;
         draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
      /*
       * For vp index and layer, if the fs requires them but the vs doesn't
       * provide them, draw (vbuf) will give us the required 0 (slot -1).
       * (This means in this case we'll also use those slots in setup, which
       * isn't necessary but they'll contain the correct (0) value.)
       */
      } else if (fsInfo->input_semantic_name[i] ==
                 TGSI_SEMANTIC_VIEWPORT_INDEX) {
         llvmpipe->viewport_index_slot = (int)vinfo->num_attribs;
         draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
      } else if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_LAYER) {
         llvmpipe->layer_slot = (int)vinfo->num_attribs;
         draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
      } else {
         /*
          * Note that we'd actually want to skip position (as we won't use
          * the attribute in the fs) but can't. The reason is that we don't
          * actually have a input/output map for setup (even though it looks
          * like we do...). Could adjust for this though even without a map
          * (in llvmpipe_create_fs_state()).
          */
         draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
      }
   }

   /* Figure out if we need bcolor as well.
    */
   for (i = 0; i < 2; i++) {
      vs_index = draw_find_shader_output(llvmpipe->draw,
                                         TGSI_SEMANTIC_BCOLOR, i);

      if (vs_index >= 0) {
         llvmpipe->bcolor_slot[i] = (int)vinfo->num_attribs;
         draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
      }
   }

   /* Figure out if we need pointsize as well.
    */
   vs_index = draw_find_shader_output(llvmpipe->draw,
                                      TGSI_SEMANTIC_PSIZE, 0);

   if (vs_index >= 0) {
      llvmpipe->psize_slot = (int)vinfo->num_attribs;
      draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
   }

   /* Figure out if we need viewport index (if it wasn't already in fs input) */
   if (llvmpipe->viewport_index_slot < 0) {
      vs_index = draw_find_shader_output(llvmpipe->draw,
                                         TGSI_SEMANTIC_VIEWPORT_INDEX,
                                         0);
      if (vs_index >= 0) {
         llvmpipe->viewport_index_slot =(int)vinfo->num_attribs;
         draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
      }
   }

   /* Figure out if we need layer (if it wasn't already in fs input) */
   if (llvmpipe->layer_slot < 0) {
      vs_index = draw_find_shader_output(llvmpipe->draw,
                                         TGSI_SEMANTIC_LAYER,
                                         0);
      if (vs_index >= 0) {
         llvmpipe->layer_slot = (int)vinfo->num_attribs;
         draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
      }
   }

   draw_compute_vertex_size(vinfo);
   lp_setup_set_vertex_info(llvmpipe->setup, vinfo);
}
Ejemplo n.º 2
0
/**
 * The vertex info describes how to convert the post-transformed vertices
 * (simple float[][4]) used by the 'draw' module into vertices for
 * rasterization.
 *
 * This function validates the vertex layout.
 */
static void
compute_vertex_info(struct llvmpipe_context *llvmpipe)
{
   const struct lp_fragment_shader *lpfs = llvmpipe->fs;
   struct vertex_info *vinfo = &llvmpipe->vertex_info;
   int vs_index;
   uint i;

   draw_prepare_shader_outputs(llvmpipe->draw);

   llvmpipe->color_slot[0] = 0;
   llvmpipe->color_slot[1] = 0;
   llvmpipe->bcolor_slot[0] = 0;
   llvmpipe->bcolor_slot[1] = 0;
   llvmpipe->viewport_index_slot = 0;
   llvmpipe->layer_slot = 0;
   llvmpipe->face_slot = 0;
   llvmpipe->psize_slot = 0;

   /*
    * Match FS inputs against VS outputs, emitting the necessary
    * attributes.  Could cache these structs and look them up with a
    * combination of fragment shader, vertex shader ids.
    */

   vinfo->num_attribs = 0;

   vs_index = draw_find_shader_output(llvmpipe->draw,
                                      TGSI_SEMANTIC_POSITION,
                                      0);

   draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index);

   for (i = 0; i < lpfs->info.base.num_inputs; i++) {
      /*
       * Search for each input in current vs output:
       */

      vs_index = draw_find_shader_output(llvmpipe->draw,
                                         lpfs->info.base.input_semantic_name[i],
                                         lpfs->info.base.input_semantic_index[i]);

      if (lpfs->info.base.input_semantic_name[i] == TGSI_SEMANTIC_COLOR &&
          lpfs->info.base.input_semantic_index[i] < 2) {
         int idx = lpfs->info.base.input_semantic_index[i];
         llvmpipe->color_slot[idx] = vinfo->num_attribs;
      }

      if (lpfs->info.base.input_semantic_name[i] == TGSI_SEMANTIC_FACE) {
         llvmpipe->face_slot = vinfo->num_attribs;
         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
      } else if (lpfs->info.base.input_semantic_name[i] == TGSI_SEMANTIC_PRIMID) {
         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
      /*
       * For vp index and layer, if the fs requires them but the vs doesn't
       * provide them, store the slot - we'll later replace the data directly
       * with zero (as required by ARB_fragment_layer_viewport). This is
       * because draw itself just redirects them to whatever was at output 0.
       * We'll also store the real vpindex/layer slot for setup use.
       */
      } else if (lpfs->info.base.input_semantic_name[i] ==
                 TGSI_SEMANTIC_VIEWPORT_INDEX) {
         if (vs_index >= 0) {
            llvmpipe->viewport_index_slot = vinfo->num_attribs;
         }
         else {
            llvmpipe->fake_vpindex_slot = vinfo->num_attribs;
         }
         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
      } else if (lpfs->info.base.input_semantic_name[i] == TGSI_SEMANTIC_LAYER) {
         if (vs_index >= 0) {
            llvmpipe->layer_slot = vinfo->num_attribs;
         }
         else {
            llvmpipe->fake_layer_slot = vinfo->num_attribs;
         }
         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
      } else {
         /*
          * Emit the requested fs attribute for all but position.
          */
         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index);
      }
   }

   /* Figure out if we need bcolor as well.
    */
   for (i = 0; i < 2; i++) {
      vs_index = draw_find_shader_output(llvmpipe->draw,
                                         TGSI_SEMANTIC_BCOLOR, i);

      if (vs_index >= 0) {
         llvmpipe->bcolor_slot[i] = vinfo->num_attribs;
         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index);
      }
   }

   /* Figure out if we need pointsize as well.
    */
   vs_index = draw_find_shader_output(llvmpipe->draw,
                                      TGSI_SEMANTIC_PSIZE, 0);

   if (vs_index >= 0) {
      llvmpipe->psize_slot = vinfo->num_attribs;
      draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
   }

   /* Figure out if we need viewport index (if it wasn't already in fs input) */
   if (llvmpipe->viewport_index_slot == 0) {
      vs_index = draw_find_shader_output(llvmpipe->draw,
                                         TGSI_SEMANTIC_VIEWPORT_INDEX,
                                         0);
      if (vs_index >= 0) {
         llvmpipe->viewport_index_slot = vinfo->num_attribs;
         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
      }
   }

   /* Figure out if we need layer (if it wasn't already in fs input) */
   if (llvmpipe->layer_slot == 0) {
      vs_index = draw_find_shader_output(llvmpipe->draw,
                                         TGSI_SEMANTIC_LAYER,
                                         0);
      if (vs_index >= 0) {
         llvmpipe->layer_slot = vinfo->num_attribs;
         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
      }
   }

   draw_compute_vertex_size(vinfo);
   lp_setup_set_vertex_info(llvmpipe->setup, vinfo);
}
Ejemplo n.º 3
0
/**
 * The vertex info describes how to convert the post-transformed vertices
 * (simple float[][4]) used by the 'draw' module into vertices for
 * rasterization.
 *
 * This function validates the vertex layout.
 */
static void
compute_vertex_info(struct llvmpipe_context *llvmpipe)
{
   const struct lp_fragment_shader *lpfs = llvmpipe->fs;
   struct vertex_info *vinfo = &llvmpipe->vertex_info;
   int vs_index;
   uint i;

   llvmpipe->color_slot[0] = -1;
   llvmpipe->color_slot[1] = -1;
   llvmpipe->bcolor_slot[0] = -1;
   llvmpipe->bcolor_slot[1] = -1;

   /*
    * Match FS inputs against VS outputs, emitting the necessary
    * attributes.  Could cache these structs and look them up with a
    * combination of fragment shader, vertex shader ids.
    */

   vinfo->num_attribs = 0;

   vs_index = draw_find_shader_output(llvmpipe->draw,
                                       TGSI_SEMANTIC_POSITION,
                                       0);

   draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index);

   for (i = 0; i < lpfs->info.base.num_inputs; i++) {
      /*
       * Search for each input in current vs output:
       */

      vs_index = draw_find_shader_output(llvmpipe->draw,
                                         lpfs->info.base.input_semantic_name[i],
                                         lpfs->info.base.input_semantic_index[i]);

      if (lpfs->info.base.input_semantic_name[i] == TGSI_SEMANTIC_COLOR &&
          lpfs->info.base.input_semantic_index[i] < 2) {
         int idx = lpfs->info.base.input_semantic_index[i];
         llvmpipe->color_slot[idx] = (int)vinfo->num_attribs;
      }

      /*
       * Emit the requested fs attribute for all but position.
       */
      draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index);
   }

   /* Figure out if we need bcolor as well.
    */
   for (i = 0; i < 2; i++) {
      vs_index = draw_find_shader_output(llvmpipe->draw,
                                         TGSI_SEMANTIC_BCOLOR, i);

      if (vs_index >= 0) {
         llvmpipe->bcolor_slot[i] = (int)vinfo->num_attribs;
         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index);
      }
   }


   /* Figure out if we need pointsize as well.
    */
   vs_index = draw_find_shader_output(llvmpipe->draw,
                                      TGSI_SEMANTIC_PSIZE, 0);

   if (vs_index >= 0) {
      llvmpipe->psize_slot = vinfo->num_attribs;
      draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
   }

   /* Figure out if we need viewport index */
   vs_index = draw_find_shader_output(llvmpipe->draw,
                                      TGSI_SEMANTIC_VIEWPORT_INDEX,
                                      0);
   if (vs_index >= 0) {
      llvmpipe->viewport_index_slot = vinfo->num_attribs;
      draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
   } else {
      llvmpipe->viewport_index_slot = 0;
   }

   /* Figure out if we need layer */
   vs_index = draw_find_shader_output(llvmpipe->draw,
                                      TGSI_SEMANTIC_LAYER,
                                      0);
   if (vs_index >= 0) {
      llvmpipe->layer_slot = vinfo->num_attribs;
      draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
   } else {
      llvmpipe->layer_slot = 0;
   }


   draw_compute_vertex_size(vinfo);
   lp_setup_set_vertex_info(llvmpipe->setup, vinfo);
}
/**
 * The vertex info describes how to convert the post-transformed vertices
 * (simple float[][4]) used by the 'draw' module into vertices for
 * rasterization.
 *
 * This function validates the vertex layout.
 */
static void
compute_vertex_info(struct llvmpipe_context *llvmpipe)
{
   const struct lp_fragment_shader *lpfs = llvmpipe->fs;
   struct vertex_info *vinfo = &llvmpipe->vertex_info;
   struct lp_shader_input *inputs = llvmpipe->inputs;
   unsigned vs_index;
   uint i;

   /*
    * Match FS inputs against VS outputs, emitting the necessary attributes.
    */

   vinfo->num_attribs = 0;

   vs_index = draw_find_shader_output(llvmpipe->draw,
                                       TGSI_SEMANTIC_POSITION,
                                       0);

   draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index);

   for (i = 0; i < lpfs->info.num_inputs; i++) {
      /*
       * Search for each input in current vs output:
       */

      vs_index = draw_find_shader_output(llvmpipe->draw,
                                         lpfs->info.input_semantic_name[i],
                                         lpfs->info.input_semantic_index[i]);
      if (vs_index < 0) {
         /*
          * This can happen with sprite coordinates - the vertex
          * shader doesn't need to provide an output as we generate
          * them internally.  However, lets keep pretending that there
          * is something there to not confuse other code.
          */
         vs_index = 0;
      }

      /* This can be pre-computed, except for flatshade:
       */
      inputs[i].usage_mask = lpfs->info.input_usage_mask[i];

      switch (lpfs->info.input_interpolate[i]) {
      case TGSI_INTERPOLATE_CONSTANT:
         inputs[i].interp = LP_INTERP_CONSTANT;
         break;
      case TGSI_INTERPOLATE_LINEAR:
         inputs[i].interp = LP_INTERP_LINEAR;
         break;
      case TGSI_INTERPOLATE_PERSPECTIVE:
         inputs[i].interp = LP_INTERP_PERSPECTIVE;
         break;
      default:
         assert(0);
         break;
      }

      switch (lpfs->info.input_semantic_name[i]) {
      case TGSI_SEMANTIC_FACE:
         inputs[i].interp = LP_INTERP_FACING;
         break;
      case TGSI_SEMANTIC_POSITION:
         /* Position was already emitted above
          */
         inputs[i].interp = LP_INTERP_POSITION;
         inputs[i].src_index = 0;
         continue;
      case TGSI_SEMANTIC_COLOR:
         /* Colors are linearly inputs[i].interpolated in the fragment shader
          * even when flatshading is active.  This just tells the
          * setup module to use coefficients with ddx==0 and
          * ddy==0.
          */
         if (llvmpipe->rasterizer->flatshade)
            inputs[i].interp = LP_INTERP_CONSTANT;
         break;

      default:
         break;
      }

      /*
       * Emit the requested fs attribute for all but position.
       */

      inputs[i].src_index = vinfo->num_attribs;
      draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index);
   }

   /* Figure out if we need pointsize as well.
    */
   vs_index = draw_find_shader_output(llvmpipe->draw,
                                      TGSI_SEMANTIC_PSIZE, 0);

   if (vs_index > 0) {
      llvmpipe->psize_slot = vinfo->num_attribs;
      draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
   }

   llvmpipe->num_inputs = lpfs->info.num_inputs;

   draw_compute_vertex_size(vinfo);

   lp_setup_set_vertex_info(llvmpipe->setup, vinfo);

   lp_setup_set_fs_inputs(llvmpipe->setup,
                          inputs,
                          lpfs->info.num_inputs);
}