Example #1
0
enum indices_mode
u_unfilled_translator(unsigned prim,
                      unsigned in_index_size,
                      unsigned nr,
                      unsigned unfilled_mode,
                      unsigned *out_prim,
                      unsigned *out_index_size,
                      unsigned *out_nr,
                      u_translate_func *out_translate)
{
   unsigned in_idx;
   unsigned out_idx;

   u_unfilled_init();

   in_idx = in_size_idx(in_index_size);
   *out_index_size = (in_index_size == 4) ? 4 : 2;
   out_idx = out_size_idx(*out_index_size);

   if (unfilled_mode == PIPE_POLYGON_MODE_POINT) 
   {
      *out_prim = PIPE_PRIM_POINTS;
      *out_nr = nr;

      switch (in_index_size)
      {
      case 1:
         *out_translate = translate_ubyte_ushort;
         return U_TRANSLATE_NORMAL;
      case 2:
         *out_translate = translate_memcpy_uint;
         return U_TRANSLATE_MEMCPY;
      case 4:
         *out_translate = translate_memcpy_ushort;
         return U_TRANSLATE_MEMCPY;
      default:
         *out_translate = translate_memcpy_uint;
         *out_nr = 0;
         assert(0);
         return U_TRANSLATE_ERROR;
      }
   }
   else {
      assert(unfilled_mode == PIPE_POLYGON_MODE_LINE);
      *out_prim = PIPE_PRIM_LINES;
      *out_translate = translate_line[in_idx][out_idx][prim];
      *out_nr = nr_lines( prim, nr );
      return U_TRANSLATE_NORMAL;
   }
}
Example #2
0
/**
 * Utility for converting unfilled polygons into points, lines, triangles.
 * Few drivers have direct support for OpenGL's glPolygonMode.
 * This function helps with converting triangles into points or lines
 * when the front and back fill modes are the same.  When there's
 * different front/back fill modes, that can be handled with the
 * 'draw' module.
 */
enum indices_mode
u_unfilled_generator(unsigned prim,
                     unsigned start,
                     unsigned nr,
                     unsigned unfilled_mode,
                     unsigned *out_prim,
                     unsigned *out_index_size,
                     unsigned *out_nr,
                     u_generate_func *out_generate)
{
   unsigned out_idx;

   u_unfilled_init();

   *out_index_size = ((start + nr) > 0xfffe) ? 4 : 2;
   out_idx = out_size_idx(*out_index_size);

   if (unfilled_mode == PIPE_POLYGON_MODE_POINT) {

      if (*out_index_size == 4)
         *out_generate = generate_linear_uint;
      else
         *out_generate = generate_linear_ushort;

      *out_prim = PIPE_PRIM_POINTS;
      *out_nr = nr;
      return U_GENERATE_LINEAR;
   }
   else {
      assert(unfilled_mode == PIPE_POLYGON_MODE_LINE);
      *out_prim = PIPE_PRIM_LINES;
      *out_generate = generate_line[out_idx][prim];
      *out_nr = nr_lines( prim, nr );

      return U_GENERATE_REUSABLE;
   }
}
Example #3
0
/**
 * Translate indexes when a driver can't support certain types
 * of drawing.  Example include:
 * - Translate 1-byte indexes into 2-byte indexes
 * - Translate PIPE_PRIM_QUADS into PIPE_PRIM_TRIANGLES when the hardware
 *   doesn't support the former.
 * - Translate from first provoking vertex to last provoking vertex and
 *   vice versa.
 *
 * Note that this function is used for indexed primitives.
 *
 * \param hw_mask  mask of (1 << PIPE_PRIM_x) flags indicating which types
 *                 of primitives are supported by the hardware.
 * \param prim  incoming PIPE_PRIM_x
 * \param in_index_size  bytes per index value (1, 2 or 4)
 * \param nr  number of incoming vertices
 * \param in_pv  incoming provoking vertex convention (PV_FIRST or PV_LAST)
 * \param out_pv  desired provoking vertex convention (PV_FIRST or PV_LAST)
 * \param prim_restart  whether primitive restart is disable or enabled
 * \param out_prim  returns new PIPE_PRIM_x we'll translate to
 * \param out_index_size  returns bytes per new index value (2 or 4)
 * \param out_nr  returns number of new vertices
 * \param out_translate  returns the translation function to use by the caller
 */
enum indices_mode
u_index_translator(unsigned hw_mask,
                   enum pipe_prim_type prim,
                   unsigned in_index_size,
                   unsigned nr,
                   unsigned in_pv,
                   unsigned out_pv,
                   unsigned prim_restart,
                   enum pipe_prim_type *out_prim,
                   unsigned *out_index_size,
                   unsigned *out_nr,
                   u_translate_func *out_translate)
{
   unsigned in_idx;
   unsigned out_idx;
   int ret = U_TRANSLATE_NORMAL;

   assert(in_index_size == 1 ||
          in_index_size == 2 ||
          in_index_size == 4);

   u_index_init();

   in_idx = in_size_idx(in_index_size);
   *out_index_size = (in_index_size == 4) ? 4 : 2;
   out_idx = out_size_idx(*out_index_size);

   if ((hw_mask & (1<<prim)) && 
       in_index_size == *out_index_size &&
       in_pv == out_pv) 
   {
      /* Index translation not really needed */
      if (in_index_size == 4)
         *out_translate = translate_memcpy_uint;
      else
         *out_translate = translate_memcpy_ushort;

      *out_prim = prim;
      *out_nr = nr;

      return U_TRANSLATE_MEMCPY;
   }
   else {
      *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim_restart][prim];

      switch (prim) {
      case PIPE_PRIM_POINTS:
         *out_prim = PIPE_PRIM_POINTS;
         *out_nr = nr;
         break;

      case PIPE_PRIM_LINES:
         *out_prim = PIPE_PRIM_LINES;
         *out_nr = nr;
         break;

      case PIPE_PRIM_LINE_STRIP:
         *out_prim = PIPE_PRIM_LINES;
         *out_nr = (nr - 1) * 2;
         break;

      case PIPE_PRIM_LINE_LOOP:
         *out_prim = PIPE_PRIM_LINES;
         *out_nr = nr * 2;
         break;

      case PIPE_PRIM_TRIANGLES:
         *out_prim = PIPE_PRIM_TRIANGLES;
         *out_nr = nr;
         break;

      case PIPE_PRIM_TRIANGLE_STRIP:
         *out_prim = PIPE_PRIM_TRIANGLES;
         *out_nr = (nr - 2) * 3;
         break;

      case PIPE_PRIM_TRIANGLE_FAN:
         *out_prim = PIPE_PRIM_TRIANGLES;
         *out_nr = (nr - 2) * 3;
         break;

      case PIPE_PRIM_QUADS:
         *out_prim = PIPE_PRIM_TRIANGLES;
         *out_nr = (nr / 4) * 6;
         break;

      case PIPE_PRIM_QUAD_STRIP:
         *out_prim = PIPE_PRIM_TRIANGLES;
         *out_nr = (nr - 2) * 3;
         break;

      case PIPE_PRIM_POLYGON:
         *out_prim = PIPE_PRIM_TRIANGLES;
         *out_nr = (nr - 2) * 3;
         break;

      case PIPE_PRIM_LINES_ADJACENCY:
         *out_prim = PIPE_PRIM_LINES_ADJACENCY;
         *out_nr = nr;
         break;

      case PIPE_PRIM_LINE_STRIP_ADJACENCY:
         *out_prim = PIPE_PRIM_LINES_ADJACENCY;
         *out_nr = (nr - 3) * 4;
         break;

      case PIPE_PRIM_TRIANGLES_ADJACENCY:
         *out_prim = PIPE_PRIM_TRIANGLES_ADJACENCY;
         *out_nr = nr;
         break;

      case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
         *out_prim = PIPE_PRIM_TRIANGLES_ADJACENCY;
         *out_nr = ((nr - 4) / 2) * 6;
         break;

      default:
         assert(0);
         *out_prim = PIPE_PRIM_POINTS;
         *out_nr = nr;
         return U_TRANSLATE_ERROR;
      }
   }

   return ret;
}
Example #4
0
/**
 * If a driver does not support a particular gallium primitive type
 * (such as PIPE_PRIM_QUAD_STRIP) this function can be used to help
 * convert the primitive into a simpler type (like PIPE_PRIM_TRIANGLES).
 *
 * The generator functions generates a number of ushort or uint indexes
 * for drawing the new type of primitive.
 *
 * Note that this function is used for non-indexed primitives.
 *
 * \param hw_mask  a bitmask of (1 << PIPE_PRIM_x) values that indicates
 *                 kind of primitives are supported by the driver.
 * \param prim  the PIPE_PRIM_x that the user wants to draw
 * \param start  index of first vertex to draw
 * \param nr  number of vertices to draw
 * \param in_pv  user's provoking vertex (PV_FIRST/LAST)
 * \param out_pv  desired proking vertex for the hardware (PV_FIRST/LAST)
 * \param out_prim  returns the new primitive type for the driver
 * \param out_index_size  returns OUT_USHORT or OUT_UINT
 * \param out_nr  returns new number of vertices to draw
 * \param out_generate  returns pointer to the generator function
 */
enum indices_mode
u_index_generator(unsigned hw_mask,
                  enum pipe_prim_type prim,
                  unsigned start,
                  unsigned nr,
                  unsigned in_pv,
                  unsigned out_pv,
                  enum pipe_prim_type *out_prim,
                  unsigned *out_index_size,
                  unsigned *out_nr,
                  u_generate_func *out_generate)
{
   unsigned out_idx;

   u_index_init();

   *out_index_size = ((start + nr) > 0xfffe) ? 4 : 2;
   out_idx = out_size_idx(*out_index_size);

   if ((hw_mask & (1<<prim)) && 
       (in_pv == out_pv)) {
       
      *out_generate = generate[out_idx][in_pv][out_pv][PIPE_PRIM_POINTS];
      *out_prim = prim;
      *out_nr = nr;
      return U_GENERATE_LINEAR;
   }
   else {
      *out_generate = generate[out_idx][in_pv][out_pv][prim];

      switch (prim) {
      case PIPE_PRIM_POINTS:
         *out_prim = PIPE_PRIM_POINTS;
         *out_nr = nr;
         return U_GENERATE_REUSABLE;

      case PIPE_PRIM_LINES:
         *out_prim = PIPE_PRIM_LINES;
         *out_nr = nr;
         return U_GENERATE_REUSABLE;

      case PIPE_PRIM_LINE_STRIP:
         *out_prim = PIPE_PRIM_LINES;
         *out_nr = (nr - 1) * 2;
         return U_GENERATE_REUSABLE;

      case PIPE_PRIM_LINE_LOOP:
         *out_prim = PIPE_PRIM_LINES;
         *out_nr = nr * 2;
         return U_GENERATE_ONE_OFF;

      case PIPE_PRIM_TRIANGLES:
         *out_prim = PIPE_PRIM_TRIANGLES;
         *out_nr = nr;
         return U_GENERATE_REUSABLE;

      case PIPE_PRIM_TRIANGLE_STRIP:
         *out_prim = PIPE_PRIM_TRIANGLES;
         *out_nr = (nr - 2) * 3;
         return U_GENERATE_REUSABLE;

      case PIPE_PRIM_TRIANGLE_FAN:
         *out_prim = PIPE_PRIM_TRIANGLES;
         *out_nr = (nr - 2) * 3;
         return U_GENERATE_REUSABLE;

      case PIPE_PRIM_QUADS:
         *out_prim = PIPE_PRIM_TRIANGLES;
         *out_nr = (nr / 4) * 6;
         return U_GENERATE_REUSABLE;

      case PIPE_PRIM_QUAD_STRIP:
         *out_prim = PIPE_PRIM_TRIANGLES;
         *out_nr = (nr - 2) * 3;
         return U_GENERATE_REUSABLE;

      case PIPE_PRIM_POLYGON:
         *out_prim = PIPE_PRIM_TRIANGLES;
         *out_nr = (nr - 2) * 3;
         return U_GENERATE_REUSABLE;

      case PIPE_PRIM_LINES_ADJACENCY:
         *out_prim = PIPE_PRIM_LINES_ADJACENCY;
         *out_nr = nr;
         return U_GENERATE_REUSABLE;

      case PIPE_PRIM_LINE_STRIP_ADJACENCY:
         *out_prim = PIPE_PRIM_LINES_ADJACENCY;
         *out_nr = (nr - 3) * 4;
         return U_GENERATE_REUSABLE;

      case PIPE_PRIM_TRIANGLES_ADJACENCY:
         *out_prim = PIPE_PRIM_TRIANGLES_ADJACENCY;
         *out_nr = nr;
         return U_GENERATE_REUSABLE;

      case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
         *out_prim = PIPE_PRIM_TRIANGLES_ADJACENCY;
         *out_nr = ((nr - 4) / 2) * 6;
         return U_GENERATE_REUSABLE;

      default:
         assert(0);
         *out_generate = generate[out_idx][in_pv][out_pv][PIPE_PRIM_POINTS];
         *out_prim = PIPE_PRIM_POINTS;
         *out_nr = nr;
         return U_TRANSLATE_ERROR;
      }
   }
}
Example #5
0
int u_index_translator( unsigned hw_mask,
                        unsigned prim,
                        unsigned in_index_size,
                        unsigned nr,
                        unsigned in_pv,
                        unsigned out_pv,
                        unsigned *out_prim,
                        unsigned *out_index_size,
                        unsigned *out_nr,
                        u_translate_func *out_translate )
{
   unsigned in_idx;
   unsigned out_idx;
   int ret = U_TRANSLATE_NORMAL;

   u_index_init();

   in_idx = in_size_idx(in_index_size);
   *out_index_size = (in_index_size == 4) ? 4 : 2;
   out_idx = out_size_idx(*out_index_size);

   if ((hw_mask & (1<<prim)) && 
       in_index_size == *out_index_size &&
       in_pv == out_pv) 
   {
      if (in_index_size == 4)
         *out_translate = translate_memcpy_uint;
      else
         *out_translate = translate_memcpy_ushort;

      *out_prim = prim;
      *out_nr = nr;

      return U_TRANSLATE_MEMCPY;
   }
   else {
      switch (prim) {
      case PIPE_PRIM_POINTS:
         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
         *out_prim = PIPE_PRIM_POINTS;
         *out_nr = nr;
         break;

      case PIPE_PRIM_LINES:
         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
         *out_prim = PIPE_PRIM_LINES;
         *out_nr = nr;
         break;

      case PIPE_PRIM_LINE_STRIP:
         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
         *out_prim = PIPE_PRIM_LINES;
         *out_nr = (nr - 1) * 2;
         break;

      case PIPE_PRIM_LINE_LOOP:
         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
         *out_prim = PIPE_PRIM_LINES;
         *out_nr = nr * 2;
         break;

      case PIPE_PRIM_TRIANGLES:
         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
         *out_prim = PIPE_PRIM_TRIANGLES;
         *out_nr = nr;
         break;

      case PIPE_PRIM_TRIANGLE_STRIP:
         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
         *out_prim = PIPE_PRIM_TRIANGLES;
         *out_nr = (nr - 2) * 3;
         break;

      case PIPE_PRIM_TRIANGLE_FAN:
         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
         *out_prim = PIPE_PRIM_TRIANGLES;
         *out_nr = (nr - 2) * 3;
         break;

      case PIPE_PRIM_QUADS:
         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
         *out_prim = PIPE_PRIM_TRIANGLES;
         *out_nr = (nr / 4) * 6;
         break;

      case PIPE_PRIM_QUAD_STRIP:
         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
         *out_prim = PIPE_PRIM_TRIANGLES;
         *out_nr = (nr - 2) * 3;
         break;

      case PIPE_PRIM_POLYGON:
         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
         *out_prim = PIPE_PRIM_TRIANGLES;
         *out_nr = (nr - 2) * 3;
         break;

      default:
         assert(0);
         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
         *out_prim = PIPE_PRIM_POINTS;
         *out_nr = nr;
         return U_TRANSLATE_ERROR;
      }
   }

   return ret;
}