static void translate_memcpy_ushort( const void *in,
unsigned start,
- unsigned nr,
+ unsigned in_nr,
+ unsigned out_nr,
+ unsigned restart_index,
void *out )
{
- memcpy(out, &((short *)in)[start], nr*sizeof(short));
+ memcpy(out, &((short *)in)[start], out_nr*sizeof(short));
}
static void translate_memcpy_uint( const void *in,
unsigned start,
- unsigned nr,
+ unsigned in_nr,
+ unsigned out_nr,
+ unsigned restart_index,
void *out )
{
- memcpy(out, &((int *)in)[start], nr*sizeof(int));
+ memcpy(out, &((int *)in)[start], out_nr*sizeof(int));
}
-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 )
+/**
+ * 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.
+ *
+ * \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,
+ unsigned prim,
+ unsigned in_index_size,
+ unsigned nr,
+ unsigned in_pv,
+ unsigned out_pv,
+ unsigned prim_restart,
+ 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;
+ assert(in_index_size == 1 ||
+ in_index_size == 2 ||
+ in_index_size == 4);
+
u_index_init();
in_idx = in_size_idx(in_index_size);
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
else {
switch (prim) {
case PIPE_PRIM_POINTS:
- *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
+ *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim_restart][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_translate = translate[in_idx][out_idx][in_pv][out_pv][prim_restart][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_translate = translate[in_idx][out_idx][in_pv][out_pv][prim_restart][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_translate = translate[in_idx][out_idx][in_pv][out_pv][prim_restart][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_translate = translate[in_idx][out_idx][in_pv][out_pv][prim_restart][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_translate = translate[in_idx][out_idx][in_pv][out_pv][prim_restart][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_translate = translate[in_idx][out_idx][in_pv][out_pv][prim_restart][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_translate = translate[in_idx][out_idx][in_pv][out_pv][prim_restart][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_translate = translate[in_idx][out_idx][in_pv][out_pv][prim_restart][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_translate = translate[in_idx][out_idx][in_pv][out_pv][prim_restart][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_translate = translate[in_idx][out_idx][in_pv][out_pv][prim_restart][prim];
*out_prim = PIPE_PRIM_POINTS;
*out_nr = nr;
return U_TRANSLATE_ERROR;
* \param out_nr returns new number of vertices to draw
* \param out_generate returns pointer to the generator function
*/
-int u_index_generator( unsigned hw_mask,
- unsigned prim,
- unsigned start,
- unsigned nr,
- unsigned in_pv,
- unsigned out_pv,
- unsigned *out_prim,
- unsigned *out_index_size,
- unsigned *out_nr,
- u_generate_func *out_generate )
-
+enum indices_mode
+u_index_generator(unsigned hw_mask,
+ unsigned prim,
+ unsigned start,
+ unsigned nr,
+ unsigned in_pv,
+ unsigned out_pv,
+ unsigned *out_prim,
+ unsigned *out_index_size,
+ unsigned *out_nr,
+ u_generate_func *out_generate)
{
unsigned out_idx;