1760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org/* Originally written by Ben Skeggs for the nv50 driver*/
2760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
3760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#ifndef U_SPLIT_PRIM_H
4760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#define U_SPLIT_PRIM_H
5760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
6760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#include "pipe/p_defines.h"
7760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#include "pipe/p_compiler.h"
8760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
9760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#include "util/u_debug.h"
10760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
11760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.orgstruct util_split_prim {
12760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   void *priv;
13760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   void (*emit)(void *priv, unsigned start, unsigned count);
14760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   void (*edge)(void *priv, boolean enabled);
15760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
16760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   unsigned mode;
17760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   unsigned start;
18760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   unsigned p_start;
19760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   unsigned p_end;
20760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
21760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   uint repeat_first:1;
22760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   uint close_first:1;
23760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   uint edgeflag_off:1;
24760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org};
25760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
26760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.orgstatic INLINE void
27760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.orgutil_split_prim_init(struct util_split_prim *s,
28760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org                  unsigned mode, unsigned start, unsigned count)
29760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org{
30760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   if (mode == PIPE_PRIM_LINE_LOOP) {
31760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      s->mode = PIPE_PRIM_LINE_STRIP;
32760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      s->close_first = 1;
33760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   } else {
34760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      s->mode = mode;
35760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      s->close_first = 0;
36760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   }
37760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   s->start = start;
38760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   s->p_start = start;
39760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   s->p_end = start + count;
40760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   s->edgeflag_off = 0;
41760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   s->repeat_first = 0;
42760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org}
43760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
44760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.orgstatic INLINE boolean
45760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.orgutil_split_prim_next(struct util_split_prim *s, unsigned max_verts)
46760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org{
47760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   int repeat = 0;
48760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
49760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   if (s->repeat_first) {
50760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      s->emit(s->priv, s->start, 1);
51760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      max_verts--;
52760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      if (s->edgeflag_off) {
53760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org         s->edge(s->priv, TRUE);
54760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org         s->edgeflag_off = FALSE;
55760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      }
56760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   }
57760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
58760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   if ((s->p_end - s->p_start) + s->close_first <= max_verts) {
59760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      s->emit(s->priv, s->p_start, s->p_end - s->p_start);
60760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      if (s->close_first)
61760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org         s->emit(s->priv, s->start, 1);
62760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      return TRUE;
63760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   }
64760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
65760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   switch (s->mode) {
66760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   case PIPE_PRIM_LINES:
67760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      max_verts &= ~1;
68760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      break;
69760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   case PIPE_PRIM_LINE_STRIP:
70760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      repeat = 1;
71760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      break;
72760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   case PIPE_PRIM_POLYGON:
73760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      max_verts--;
74760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      s->emit(s->priv, s->p_start, max_verts);
75760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      s->edge(s->priv, FALSE);
76760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      s->emit(s->priv, s->p_start + max_verts, 1);
77760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      s->p_start += max_verts;
78760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      s->repeat_first = TRUE;
79760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      s->edgeflag_off = TRUE;
80760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      return FALSE;
81760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   case PIPE_PRIM_TRIANGLES:
82760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      max_verts = max_verts - (max_verts % 3);
83760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      break;
84760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   case PIPE_PRIM_TRIANGLE_STRIP:
85760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      /* to ensure winding stays correct, always split
86760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org       * on an even number of generated triangles
87760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org       */
88760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      max_verts = max_verts & ~1;
89760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      repeat = 2;
90760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      break;
91760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   case PIPE_PRIM_TRIANGLE_FAN:
92760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      s->repeat_first = TRUE;
93760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      repeat = 1;
94760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      break;
95760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   case PIPE_PRIM_QUADS:
96760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      max_verts &= ~3;
97760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      break;
98760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   case PIPE_PRIM_QUAD_STRIP:
99760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      max_verts &= ~1;
100760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      repeat = 2;
101760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      break;
102760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   case PIPE_PRIM_POINTS:
103760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      break;
104760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   default:
105760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      /* TODO: implement adjacency primitives */
106760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      assert(0);
107760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   }
108760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
109760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   s->emit (s->priv, s->p_start, max_verts);
110760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   s->p_start += (max_verts - repeat);
111760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   return FALSE;
112760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org}
113760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
114760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#endif /* U_SPLIT_PRIM_H */
115