104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu/*
204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * Mesa 3-D graphics library
304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * Version:  7.9
404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu *
504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * Copyright (C) 2010 LunarG Inc.
704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu *
804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * Permission is hereby granted, free of charge, to any person obtaining a
904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * copy of this software and associated documentation files (the "Software"),
1004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * to deal in the Software without restriction, including without limitation
1104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * and/or sell copies of the Software, and to permit persons to whom the
1304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * Software is furnished to do so, subject to the following conditions:
1404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu *
1504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * The above copyright notice and this permission notice shall be included
1604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * in all copies or substantial portions of the Software.
1704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu *
1804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
2104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * DEALINGS IN THE SOFTWARE.
2504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu */
2604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
2704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wustatic void
2804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I WuFUNC(FUNC_VARS)
2904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu{
3004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   unsigned first, incr;
3104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   LOCAL_VARS
3204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
3304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   /*
3404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu    * prim, start, count, and max_count_{simple,loop,fan} should have been
3504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu    * defined
3604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu    */
3704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   if (0) {
3804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      debug_printf("%s: prim 0x%x, start %d, count %d, max_count_simple %d, "
3904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                   "max_count_loop %d, max_count_fan %d\n",
4004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                   __FUNCTION__, prim, start, count, max_count_simple,
4104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                   max_count_loop, max_count_fan);
4204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   }
4304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
4404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   draw_pt_split_prim(prim, &first, &incr);
4504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   /* sanitize primitive length */
4604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   count = draw_pt_trim_count(count, first, incr);
4704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   if (count < first)
4804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      return;
4904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
50a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu   /* try flushing the entire primitive */
51a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu   if (PRIMITIVE(start, count))
52a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu      return;
53a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu
5404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   /* must be able to at least flush two complete primitives */
5504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   assert(max_count_simple >= first + incr &&
5604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu          max_count_loop >= first + incr &&
5704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu          max_count_fan >= first + incr);
5804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
5904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   /* no splitting required */
6004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   if (count <= max_count_simple) {
6104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      SEGMENT_SIMPLE(0x0, start, count);
6204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   }
6304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   else {
6404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      const unsigned rollback = first - incr;
6504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      unsigned flags = DRAW_SPLIT_AFTER, seg_start = 0, seg_max;
6604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
6704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      /*
6804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu       * Both count and seg_max below are explicitly trimmed.  Because
6904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu       *
7004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu       *   seg_start = N * (seg_max - rollback) = N' * incr,
7104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu       *
7204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu       * we have
7304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu       *
7404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu       *   remaining = count - seg_start = first + N'' * incr.
7504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu       *
7604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu       * That is, remaining is implicitly trimmed.
7704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu       */
7804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      switch (prim) {
7904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      case PIPE_PRIM_POINTS:
8004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      case PIPE_PRIM_LINES:
8104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      case PIPE_PRIM_LINE_STRIP:
8204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      case PIPE_PRIM_TRIANGLES:
8304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      case PIPE_PRIM_TRIANGLE_STRIP:
8404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      case PIPE_PRIM_QUADS:
8504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      case PIPE_PRIM_QUAD_STRIP:
8604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      case PIPE_PRIM_LINES_ADJACENCY:
8704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      case PIPE_PRIM_LINE_STRIP_ADJACENCY:
8804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      case PIPE_PRIM_TRIANGLES_ADJACENCY:
8904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
9004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         seg_max =
9104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            draw_pt_trim_count(MIN2(max_count_simple, count), first, incr);
9204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         if (prim == PIPE_PRIM_TRIANGLE_STRIP ||
9304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu             prim == PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY) {
9404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            /* make sure we flush even number of triangles at a time */
9504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            if (seg_max < count && !(((seg_max - first) / incr) & 1))
9604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu               seg_max -= incr;
9704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         }
9804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
9904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         do {
10004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            const unsigned remaining = count - seg_start;
10104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
10204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            if (remaining > seg_max) {
10304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu               SEGMENT_SIMPLE(flags, start + seg_start, seg_max);
10404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu               seg_start += seg_max - rollback;
10504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
10604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu               flags |= DRAW_SPLIT_BEFORE;
10704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            }
10804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            else {
10904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu               flags &= ~DRAW_SPLIT_AFTER;
11004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
11104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu               SEGMENT_SIMPLE(flags, start + seg_start, remaining);
11204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu               seg_start += remaining;
11304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            }
11404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         } while (seg_start < count);
11504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         break;
11604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
11704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      case PIPE_PRIM_LINE_LOOP:
11804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         seg_max =
11904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            draw_pt_trim_count(MIN2(max_count_loop, count), first, incr);
12004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
12104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         do {
12204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            const unsigned remaining = count - seg_start;
12304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
12404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            if (remaining > seg_max) {
12504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu               SEGMENT_LOOP(flags, start + seg_start, seg_max, start);
12604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu               seg_start += seg_max - rollback;
12704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
12804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu               flags |= DRAW_SPLIT_BEFORE;
12904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            }
13004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            else {
13104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu               flags &= ~DRAW_SPLIT_AFTER;
13204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
13304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu               SEGMENT_LOOP(flags, start + seg_start, remaining, start);
13404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu               seg_start += remaining;
13504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            }
13604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         } while (seg_start < count);
13704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         break;
13804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
13904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      case PIPE_PRIM_TRIANGLE_FAN:
14004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      case PIPE_PRIM_POLYGON:
14104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         seg_max =
14204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            draw_pt_trim_count(MIN2(max_count_fan, count), first, incr);
14304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
14404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         do {
14504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            const unsigned remaining = count - seg_start;
14604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
14704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            if (remaining > seg_max) {
14804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu               SEGMENT_FAN(flags, start + seg_start, seg_max, start);
14904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu               seg_start += seg_max - rollback;
15004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
15104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu               flags |= DRAW_SPLIT_BEFORE;
15204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            }
15304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            else {
15404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu               flags &= ~DRAW_SPLIT_AFTER;
15504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
15604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu               SEGMENT_FAN(flags, start + seg_start, remaining, start);
15704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu               seg_start += remaining;
15804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            }
15904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         } while (seg_start < count);
16004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         break;
16104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
16204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      default:
16304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         assert(0);
16404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         break;
16504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      }
16604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   }
16704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu}
16804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
16904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#undef FUNC
17004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#undef FUNC_VARS
17104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#undef LOCAL_VARS
17204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
173a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu#undef PRIMITIVE
17404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#undef SEGMENT_SIMPLE
17504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#undef SEGMENT_LOOP
17604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#undef SEGMENT_FAN
177