1760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org/*
2760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * Mesa 3-D graphics library
3760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * Version:  7.9
4760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org *
5760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
6760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * Copyright (C) 2010 LunarG Inc.
7760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org *
8760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
9760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * copy of this software and associated documentation files (the "Software"),
10760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * to deal in the Software without restriction, including without limitation
11760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
13760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * Software is furnished to do so, subject to the following conditions:
14760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org *
15760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * The above copyright notice and this permission notice shall be included
16760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * in all copies or substantial portions of the Software.
17760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org *
18760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * DEALINGS IN THE SOFTWARE.
25760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org */
26760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
27760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.orgstatic void
28760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.orgFUNC(FUNC_VARS)
29760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org{
30760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   unsigned first, incr;
31760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   LOCAL_VARS
32760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
33760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   /*
34760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org    * prim, start, count, and max_count_{simple,loop,fan} should have been
35760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org    * defined
36760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org    */
37760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   if (0) {
38760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      debug_printf("%s: prim 0x%x, start %d, count %d, max_count_simple %d, "
39760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org                   "max_count_loop %d, max_count_fan %d\n",
40760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org                   __FUNCTION__, prim, start, count, max_count_simple,
41760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org                   max_count_loop, max_count_fan);
42760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   }
43760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
44760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   draw_pt_split_prim(prim, &first, &incr);
45760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   /* sanitize primitive length */
46760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   count = draw_pt_trim_count(count, first, incr);
47760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   if (count < first)
48760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      return;
49760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
50760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   /* try flushing the entire primitive */
51760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   if (PRIMITIVE(start, count))
52760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      return;
53760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
54760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   /* must be able to at least flush two complete primitives */
55760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   assert(max_count_simple >= first + incr &&
56760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org          max_count_loop >= first + incr &&
57760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org          max_count_fan >= first + incr);
58760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
59760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   /* no splitting required */
60760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   if (count <= max_count_simple) {
61760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      SEGMENT_SIMPLE(0x0, start, count);
62760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   }
63760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   else {
64760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      const unsigned rollback = first - incr;
65760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      unsigned flags = DRAW_SPLIT_AFTER, seg_start = 0, seg_max;
66760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
67760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      /*
68760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org       * Both count and seg_max below are explicitly trimmed.  Because
69760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org       *
70760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org       *   seg_start = N * (seg_max - rollback) = N' * incr,
71760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org       *
72760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org       * we have
73760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org       *
74760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org       *   remaining = count - seg_start = first + N'' * incr.
75760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org       *
76760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org       * That is, remaining is implicitly trimmed.
77760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org       */
78760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      switch (prim) {
79760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      case PIPE_PRIM_POINTS:
80760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      case PIPE_PRIM_LINES:
81760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      case PIPE_PRIM_LINE_STRIP:
82760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      case PIPE_PRIM_TRIANGLES:
83760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      case PIPE_PRIM_TRIANGLE_STRIP:
84760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      case PIPE_PRIM_QUADS:
85760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      case PIPE_PRIM_QUAD_STRIP:
86760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      case PIPE_PRIM_LINES_ADJACENCY:
87760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      case PIPE_PRIM_LINE_STRIP_ADJACENCY:
88760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      case PIPE_PRIM_TRIANGLES_ADJACENCY:
89760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
90760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org         seg_max =
91760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org            draw_pt_trim_count(MIN2(max_count_simple, count), first, incr);
92760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org         if (prim == PIPE_PRIM_TRIANGLE_STRIP ||
93760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org             prim == PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY) {
94760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org            /* make sure we flush even number of triangles at a time */
95760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org            if (seg_max < count && !(((seg_max - first) / incr) & 1))
96760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org               seg_max -= incr;
97760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org         }
98760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
99760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org         do {
100760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org            const unsigned remaining = count - seg_start;
101760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
102760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org            if (remaining > seg_max) {
103760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org               SEGMENT_SIMPLE(flags, start + seg_start, seg_max);
104760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org               seg_start += seg_max - rollback;
105760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
106760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org               flags |= DRAW_SPLIT_BEFORE;
107760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org            }
108760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org            else {
109760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org               flags &= ~DRAW_SPLIT_AFTER;
110760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
111760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org               SEGMENT_SIMPLE(flags, start + seg_start, remaining);
112760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org               seg_start += remaining;
113760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org            }
114760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org         } while (seg_start < count);
115760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org         break;
116760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
117760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      case PIPE_PRIM_LINE_LOOP:
118760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org         seg_max =
119760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org            draw_pt_trim_count(MIN2(max_count_loop, count), first, incr);
120760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
121760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org         do {
122760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org            const unsigned remaining = count - seg_start;
123760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
124760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org            if (remaining > seg_max) {
125760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org               SEGMENT_LOOP(flags, start + seg_start, seg_max, start);
126760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org               seg_start += seg_max - rollback;
127760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
128760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org               flags |= DRAW_SPLIT_BEFORE;
129760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org            }
130760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org            else {
131760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org               flags &= ~DRAW_SPLIT_AFTER;
132760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
133760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org               SEGMENT_LOOP(flags, start + seg_start, remaining, start);
134760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org               seg_start += remaining;
135760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org            }
136760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org         } while (seg_start < count);
137760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org         break;
138760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
139760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      case PIPE_PRIM_TRIANGLE_FAN:
140760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      case PIPE_PRIM_POLYGON:
141760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org         seg_max =
142760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org            draw_pt_trim_count(MIN2(max_count_fan, count), first, incr);
143760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
144760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org         do {
145760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org            const unsigned remaining = count - seg_start;
146760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
147760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org            if (remaining > seg_max) {
148760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org               SEGMENT_FAN(flags, start + seg_start, seg_max, start);
149760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org               seg_start += seg_max - rollback;
150760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
151760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org               flags |= DRAW_SPLIT_BEFORE;
152760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org            }
153760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org            else {
154760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org               flags &= ~DRAW_SPLIT_AFTER;
155760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
156760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org               SEGMENT_FAN(flags, start + seg_start, remaining, start);
157760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org               seg_start += remaining;
158760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org            }
159760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org         } while (seg_start < count);
160760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org         break;
161760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
162760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      default:
163760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org         assert(0);
164760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org         break;
165760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      }
166760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   }
167760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org}
168760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
169760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#undef FUNC
170760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#undef FUNC_VARS
171760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#undef LOCAL_VARS
172760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
173760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#undef PRIMITIVE
174760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#undef SEGMENT_SIMPLE
175760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#undef SEGMENT_LOOP
176760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#undef SEGMENT_FAN
177