10dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri/* Originally written by Ben Skeggs for the nv50 driver*/
2c7111f321ca16f2c72cc59975b728a566daae95aVinson Lee
3c7111f321ca16f2c72cc59975b728a566daae95aVinson Lee#ifndef U_SPLIT_PRIM_H
4c7111f321ca16f2c72cc59975b728a566daae95aVinson Lee#define U_SPLIT_PRIM_H
5c7111f321ca16f2c72cc59975b728a566daae95aVinson Lee
6cc3e322d967e51a8c0fa794a310a93ee4b684a91Vinson Lee#include "pipe/p_defines.h"
7cc3e322d967e51a8c0fa794a310a93ee4b684a91Vinson Lee#include "pipe/p_compiler.h"
8cc3e322d967e51a8c0fa794a310a93ee4b684a91Vinson Lee
9cc3e322d967e51a8c0fa794a310a93ee4b684a91Vinson Lee#include "util/u_debug.h"
100dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri
11eee5cea385b6871fa934a7882b2f214e3cbace8bLuca Barbieristruct util_split_prim {
120dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   void *priv;
130dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   void (*emit)(void *priv, unsigned start, unsigned count);
140dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   void (*edge)(void *priv, boolean enabled);
150dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri
160dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   unsigned mode;
170dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   unsigned start;
180dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   unsigned p_start;
190dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   unsigned p_end;
200dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri
210dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   uint repeat_first:1;
220dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   uint close_first:1;
230dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   uint edgeflag_off:1;
240dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri};
250dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri
260dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieristatic INLINE void
27eee5cea385b6871fa934a7882b2f214e3cbace8bLuca Barbieriutil_split_prim_init(struct util_split_prim *s,
280dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri                  unsigned mode, unsigned start, unsigned count)
290dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri{
300dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   if (mode == PIPE_PRIM_LINE_LOOP) {
310dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      s->mode = PIPE_PRIM_LINE_STRIP;
320dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      s->close_first = 1;
330dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   } else {
340dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      s->mode = mode;
350dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      s->close_first = 0;
360dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   }
370dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   s->start = start;
380dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   s->p_start = start;
390dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   s->p_end = start + count;
400dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   s->edgeflag_off = 0;
410dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   s->repeat_first = 0;
420dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri}
430dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri
440dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieristatic INLINE boolean
45eee5cea385b6871fa934a7882b2f214e3cbace8bLuca Barbieriutil_split_prim_next(struct util_split_prim *s, unsigned max_verts)
460dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri{
470dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   int repeat = 0;
480dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri
490dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   if (s->repeat_first) {
500dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      s->emit(s->priv, s->start, 1);
510dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      max_verts--;
520dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      if (s->edgeflag_off) {
530dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri         s->edge(s->priv, TRUE);
540dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri         s->edgeflag_off = FALSE;
550dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      }
560dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   }
570dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri
58c0eb479e0782c063a1a781f81b99a18ef649e9efLuca Barbieri   if ((s->p_end - s->p_start) + s->close_first <= max_verts) {
590dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      s->emit(s->priv, s->p_start, s->p_end - s->p_start);
600dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      if (s->close_first)
610dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri         s->emit(s->priv, s->start, 1);
620dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      return TRUE;
630dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   }
640dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri
650dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   switch (s->mode) {
660dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   case PIPE_PRIM_LINES:
670dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      max_verts &= ~1;
680dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      break;
690dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   case PIPE_PRIM_LINE_STRIP:
700dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      repeat = 1;
710dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      break;
720dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   case PIPE_PRIM_POLYGON:
730dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      max_verts--;
740dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      s->emit(s->priv, s->p_start, max_verts);
750dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      s->edge(s->priv, FALSE);
760dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      s->emit(s->priv, s->p_start + max_verts, 1);
770dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      s->p_start += max_verts;
780dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      s->repeat_first = TRUE;
790dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      s->edgeflag_off = TRUE;
800dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      return FALSE;
810dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   case PIPE_PRIM_TRIANGLES:
820dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      max_verts = max_verts - (max_verts % 3);
830dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      break;
840dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   case PIPE_PRIM_TRIANGLE_STRIP:
850dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      /* to ensure winding stays correct, always split
860dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri       * on an even number of generated triangles
870dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri       */
880dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      max_verts = max_verts & ~1;
890dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      repeat = 2;
900dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      break;
910dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   case PIPE_PRIM_TRIANGLE_FAN:
920dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      s->repeat_first = TRUE;
930dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      repeat = 1;
940dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      break;
950dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   case PIPE_PRIM_QUADS:
960dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      max_verts &= ~3;
970dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      break;
980dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   case PIPE_PRIM_QUAD_STRIP:
990dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      max_verts &= ~1;
1000dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      repeat = 2;
1010dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      break;
10258b104d7f0890434aadbdebcd6002ba0a0e132ecLuca Barbieri   case PIPE_PRIM_POINTS:
1030dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri      break;
10458b104d7f0890434aadbdebcd6002ba0a0e132ecLuca Barbieri   default:
10558b104d7f0890434aadbdebcd6002ba0a0e132ecLuca Barbieri      /* TODO: implement adjacency primitives */
10658b104d7f0890434aadbdebcd6002ba0a0e132ecLuca Barbieri      assert(0);
1070dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   }
1080dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri
1090dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   s->emit (s->priv, s->p_start, max_verts);
1100dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   s->p_start += (max_verts - repeat);
1110dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri   return FALSE;
1120dcf0f9dfaa23b08d2bc20f8cbd02550c2632e52Luca Barbieri}
113c7111f321ca16f2c72cc59975b728a566daae95aVinson Lee
114c7111f321ca16f2c72cc59975b728a566daae95aVinson Lee#endif /* U_SPLIT_PRIM_H */
115