예제 #1
0
/**
 * Return total number of the shader outputs.  This function is similar to
 * draw_current_shader_outputs() but this function also counts any extra
 * vertex/geometry output attributes that may be filled in by some draw
 * stages (such as AA point, AA line).
 *
 * If geometry shader is present, its output will be returned,
 * if not vertex shader is used.
 */
uint
draw_num_shader_outputs(const struct draw_context *draw)
{
   const struct tgsi_shader_info *info = draw_get_shader_info(draw);
   uint count;

   count = info->num_outputs;
   count += draw->extra_shader_outputs.num;

   return count;
}
예제 #2
0
/**
 * Ask the draw module for the location/slot of the given vertex attribute in
 * a post-transformed vertex.
 *
 * With this function, drivers that use the draw module should have no reason
 * to track the current vertex/geometry shader.
 *
 * Note that the draw module may sometimes generate vertices with extra
 * attributes (such as texcoords for AA lines).  The driver can call this
 * function to find those attributes.
 *
 * Zero is returned if the attribute is not found since this is
 * a don't care / undefined situtation.  Returning -1 would be a bit more
 * work for the drivers.
 */
int
draw_find_shader_output(const struct draw_context *draw,
                        uint semantic_name, uint semantic_index)
{
   const struct tgsi_shader_info *info = draw_get_shader_info(draw);
   uint i;

   for (i = 0; i < info->num_outputs; i++) {
      if (info->output_semantic_name[i] == semantic_name &&
          info->output_semantic_index[i] == semantic_index)
         return i;
   }

   /* Search the extra vertex attributes */
   for (i = 0; i < draw->extra_shader_outputs.num; i++) {
      if (draw->extra_shader_outputs.semantic_name[i] == semantic_name &&
          draw->extra_shader_outputs.semantic_index[i] == semantic_index) {
         return draw->extra_shader_outputs.slot[i];
      }
   }

   return 0;
}
예제 #3
0
/* Update state.  Could further delay this until we hit the first
 * primitive that really requires clipping.
 */
static void 
clip_init_state( struct draw_stage *stage )
{
   struct clip_stage *clipper = clip_stage( stage );
   const struct draw_context *draw = stage->draw;
   const struct draw_fragment_shader *fs = draw->fs.fragment_shader;
   const struct tgsi_shader_info *info = draw_get_shader_info(draw);
   uint i, j;

   /* We need to know for each attribute what kind of interpolation is
    * done on it (flat, smooth or noperspective).  But the information
    * is not directly accessible for outputs, only for inputs.  So we
    * have to match semantic name and index between the VS (or GS/ES)
    * outputs and the FS inputs to get to the interpolation mode.
    *
    * The only hitch is with gl_FrontColor/gl_BackColor which map to
    * gl_Color, and their Secondary versions.  First there are (up to)
    * two outputs for one input, so we tuck the information in a
    * specific array.  Second if they don't have qualifiers, the
    * default value has to be picked from the global shade mode.
    *
    * Of course, if we don't have a fragment shader in the first
    * place, defaults should be used.
    */

   /* First pick up the interpolation mode for
    * gl_Color/gl_SecondaryColor, with the correct default.
    */
   int indexed_interp[2];
   indexed_interp[0] = indexed_interp[1] = draw->rasterizer->flatshade ?
      TGSI_INTERPOLATE_CONSTANT : TGSI_INTERPOLATE_PERSPECTIVE;

   if (fs) {
      for (i = 0; i < fs->info.num_inputs; i++) {
         if (fs->info.input_semantic_name[i] == TGSI_SEMANTIC_COLOR) {
            if (fs->info.input_interpolate[i] != TGSI_INTERPOLATE_COLOR)
               indexed_interp[fs->info.input_semantic_index[i]] = fs->info.input_interpolate[i];
         }
      }
   }

   /* Then resolve the interpolation mode for every output attribute.
    *
    * Given how the rest of the code, the most efficient way is to
    * have a vector of flat-mode attributes, and a mask for
    * noperspective attributes.
    */

   clipper->num_flat_attribs = 0;
   memset(clipper->noperspective_attribs, 0, sizeof(clipper->noperspective_attribs));
   for (i = 0; i < info->num_outputs; i++) {
      /* Find the interpolation mode for a specific attribute */
      int interp = find_interp(fs, indexed_interp,
                               info->output_semantic_name[i],
                               info->output_semantic_index[i]);
      /* If it's flat, add it to the flat vector.  Otherwise update
       * the noperspective mask.
       */

      if (interp == TGSI_INTERPOLATE_CONSTANT) {
         clipper->flat_attribs[clipper->num_flat_attribs] = i;
         clipper->num_flat_attribs++;
      } else
         clipper->noperspective_attribs[i] = interp == TGSI_INTERPOLATE_LINEAR;
   }
   /* Search the extra vertex attributes */
   for (j = 0; j < draw->extra_shader_outputs.num; j++) {
      /* Find the interpolation mode for a specific attribute */
      int interp = find_interp(fs, indexed_interp,
                               draw->extra_shader_outputs.semantic_name[j],
                               draw->extra_shader_outputs.semantic_index[j]);
      /* If it's flat, add it to the flat vector.  Otherwise update
       * the noperspective mask.
       */
      if (interp == TGSI_INTERPOLATE_CONSTANT) {
         clipper->flat_attribs[clipper->num_flat_attribs] = i + j;
         clipper->num_flat_attribs++;
      } else
         clipper->noperspective_attribs[i + j] = interp == TGSI_INTERPOLATE_LINEAR;
   }
   
   stage->tri = clip_tri;
   stage->line = clip_line;
}