104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu/*
204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * Mesa 3-D graphics library
304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu *
4877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca * Copyright 2007-2008 VMware, Inc.
504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * Copyright (C) 2010 LunarG Inc.
604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu *
704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * Permission is hereby granted, free of charge, to any person obtaining a
804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * copy of this software and associated documentation files (the "Software"),
904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * to deal in the Software without restriction, including without limitation
1004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * and/or sell copies of the Software, and to permit persons to whom the
1204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * Software is furnished to do so, subject to the following conditions:
1304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu *
1404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * The above copyright notice and this permission notice shall be included
1504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * in all copies or substantial portions of the Software.
1604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu *
1704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
2004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * DEALINGS IN THE SOFTWARE.
2404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu */
2504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
2604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#define CONCAT2(name, elt_type) name ## elt_type
2704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#define CONCAT(name, elt_type) CONCAT2(name, elt_type)
2804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
2904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#ifdef ELT_TYPE
3004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
3104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu/**
3204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * Fetch all elements in [min_index, max_index] with bias, and use the
3304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * (rebased) index buffer as the draw elements.
3404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu */
3504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wustatic boolean
36a072f0e186522f9de2848989422ad0244f65c961Chia-I WuCONCAT(vsplit_primitive_, ELT_TYPE)(struct vsplit_frontend *vsplit,
37a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu                                    unsigned istart, unsigned icount)
3804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu{
3904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   struct draw_context *draw = vsplit->draw;
40185ed2105829d6f5eb19edb9abbf0d7977e157c3Brian Paul   const ELT_TYPE *ib = (const ELT_TYPE *) draw->pt.user.elts;
4104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   const unsigned min_index = draw->pt.user.min_index;
4204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   const unsigned max_index = draw->pt.user.max_index;
4304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   const int elt_bias = draw->pt.user.eltBias;
4404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   unsigned fetch_start, fetch_count;
45a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu   const ushort *draw_elts = NULL;
4604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   unsigned i;
475104ed3dbf18d47736fc67a8e3e317ea18360fa8Zack Rusin   const unsigned start = istart;
485104ed3dbf18d47736fc67a8e3e317ea18360fa8Zack Rusin   const unsigned end = istart + icount;
49713230ff39cd22a2082c12b937889c3ef81973acJosé Fonseca
50bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin   /* If the index buffer overflows we'll need to run
51bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin    * through the normal paths */
527a55c436c64a8bb031c8823522cde8f3adc67d89Roland Scheidegger   if (end >= draw->pt.user.eltMax ||
537a55c436c64a8bb031c8823522cde8f3adc67d89Roland Scheidegger       end < istart)
54bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin      return FALSE;
55bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin
56a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu   /* use the ib directly */
57a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu   if (min_index == 0 && sizeof(ib[0]) == sizeof(draw_elts[0])) {
58a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu      if (icount > vsplit->max_vertices)
59a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu         return FALSE;
60a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu
61bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin      for (i = 0; i < icount; i++) {
62bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin         ELT_TYPE idx = DRAW_GET_IDX(ib, start + i);
6394f9ea03a12fe1adf90c0e5defb0063cd568b537Roland Scheidegger         if (idx < min_index || idx > max_index) {
643733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca            debug_printf("warning: index out of range\n");
653733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca         }
66a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu      }
671883e1d3e972f552aaf6225390a4dc17484fcd3cJosé Fonseca      draw_elts = (const ushort *) (ib + istart);
68a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu   }
69a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu   else {
70a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu      /* have to go through vsplit->draw_elts */
71a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu      if (icount > vsplit->segment_size)
72a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu         return FALSE;
73a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu   }
7404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
7504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   /* this is faster only when we fetch less elements than the normal path */
763dedd39cdd198afa54ba5b53384d6be2040f9485José Fonseca   if (max_index - min_index > icount - 1)
7704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      return FALSE;
7804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
79f03191048668ebcda56053f4c908e1ac0d98edd0Brian Paul   if (elt_bias < 0 && (int) min_index < -elt_bias)
8004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      return FALSE;
8104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
8204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   /* why this check? */
8304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   for (i = 0; i < draw->pt.nr_vertex_elements; i++) {
8404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      if (draw->pt.vertex_element[i].instance_divisor)
8504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         return FALSE;
8604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   }
8704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
883dedd39cdd198afa54ba5b53384d6be2040f9485José Fonseca   fetch_start = min_index + elt_bias;
893dedd39cdd198afa54ba5b53384d6be2040f9485José Fonseca   fetch_count = max_index - min_index + 1;
903dedd39cdd198afa54ba5b53384d6be2040f9485José Fonseca
91bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin   /* Check for overflow in the fetch_start */
92bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin   if (fetch_start < min_index || fetch_start < elt_bias)
93bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin      return FALSE;
94bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin
95a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu   if (!draw_elts) {
9604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      if (min_index == 0) {
97bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin         for (i = 0; i < icount; i++) {
98bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin            ELT_TYPE idx = DRAW_GET_IDX(ib, i + start);
9904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
100dcbc9be38ecea30506198d0db037cbf532f070e4José Fonseca            if (idx < min_index || idx > max_index) {
1013733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca               debug_printf("warning: index out of range\n");
10294f9ea03a12fe1adf90c0e5defb0063cd568b537Roland Scheidegger            }
103bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin            vsplit->draw_elts[i] = (ushort) idx;
10404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         }
10504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      }
10604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      else {
107bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin         for (i = 0; i < icount; i++) {
108bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin            ELT_TYPE idx = DRAW_GET_IDX(ib, i + start);
10904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
110dcbc9be38ecea30506198d0db037cbf532f070e4José Fonseca            if (idx < min_index || idx > max_index) {
1113733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca               debug_printf("warning: index out of range\n");
11294f9ea03a12fe1adf90c0e5defb0063cd568b537Roland Scheidegger            }
113bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin            vsplit->draw_elts[i] = (ushort) (idx - min_index);
11404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         }
11504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      }
11604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
11704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      draw_elts = vsplit->draw_elts;
11804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   }
11904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
12004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   return vsplit->middle->run_linear_elts(vsplit->middle,
12104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                                          fetch_start, fetch_count,
122a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu                                          draw_elts, icount, 0x0);
12304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu}
12404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
12504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu/**
12604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * Use the cache to prepare the fetch and draw elements, and flush.
12704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu *
12804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * When spoken is TRUE, ispoken replaces istart;  When close is TRUE, iclose is
12904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * appended.
13004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu */
131a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline void
13204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I WuCONCAT(vsplit_segment_cache_, ELT_TYPE)(struct vsplit_frontend *vsplit,
13304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                                        unsigned flags,
13404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                                        unsigned istart, unsigned icount,
13504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                                        boolean spoken, unsigned ispoken,
13604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                                        boolean close, unsigned iclose)
13704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu{
13804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   struct draw_context *draw = vsplit->draw;
139185ed2105829d6f5eb19edb9abbf0d7977e157c3Brian Paul   const ELT_TYPE *ib = (const ELT_TYPE *) draw->pt.user.elts;
14004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   const int ibias = draw->pt.user.eltBias;
14104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   unsigned i;
14204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
14304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   assert(icount + !!close <= vsplit->segment_size);
14404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
14504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   vsplit_clear_cache(vsplit);
14604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
14704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   spoken = !!spoken;
14804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   if (ibias == 0) {
14904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      if (spoken)
150bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin         ADD_CACHE(vsplit, ib, 0, ispoken, 0);
15104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
152bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin      for (i = spoken; i < icount; i++) {
153bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin         ADD_CACHE(vsplit, ib, istart, i, 0);
154bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin      }
15504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
15604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      if (close)
157bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin         ADD_CACHE(vsplit, ib, 0, iclose, 0);
15804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   }
15978a997f72841310620d18daa9015633343d04db1Roland Scheidegger   else {
16004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      if (spoken)
161bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin         ADD_CACHE(vsplit, ib, 0, ispoken, ibias);
16204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
16304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      for (i = spoken; i < icount; i++)
164bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin         ADD_CACHE(vsplit, ib, istart, i, ibias);
16504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
16604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      if (close)
167bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin         ADD_CACHE(vsplit, ib, 0, iclose, ibias);
16804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   }
16904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
17004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   vsplit_flush_cache(vsplit, flags);
17104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu}
17204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
17304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wustatic void
17404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I WuCONCAT(vsplit_segment_simple_, ELT_TYPE)(struct vsplit_frontend *vsplit,
17504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                                         unsigned flags,
17604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                                         unsigned istart,
17704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                                         unsigned icount)
17804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu{
17904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   CONCAT(vsplit_segment_cache_, ELT_TYPE)(vsplit,
18004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         flags, istart, icount, FALSE, 0, FALSE, 0);
18104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu}
18204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
18304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wustatic void
18404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I WuCONCAT(vsplit_segment_loop_, ELT_TYPE)(struct vsplit_frontend *vsplit,
18504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                                       unsigned flags,
18604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                                       unsigned istart,
18704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                                       unsigned icount,
18804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                                       unsigned i0)
18904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu{
19004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   const boolean close_loop = ((flags) == DRAW_SPLIT_BEFORE);
19104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
19204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   CONCAT(vsplit_segment_cache_, ELT_TYPE)(vsplit,
19304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         flags, istart, icount, FALSE, 0, close_loop, i0);
19404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu}
19504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
19604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wustatic void
19704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I WuCONCAT(vsplit_segment_fan_, ELT_TYPE)(struct vsplit_frontend *vsplit,
19804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                                      unsigned flags,
19904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                                      unsigned istart,
20004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                                      unsigned icount,
20104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                                      unsigned i0)
20204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu{
20304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   const boolean use_spoken = (((flags) & DRAW_SPLIT_BEFORE) != 0);
20404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
20504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   CONCAT(vsplit_segment_cache_, ELT_TYPE)(vsplit,
20604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         flags, istart, icount, use_spoken, i0, FALSE, 0);
20704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu}
20804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
20904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#define LOCAL_VARS                                                         \
21004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   struct vsplit_frontend *vsplit = (struct vsplit_frontend *) frontend;   \
21104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   const unsigned prim = vsplit->prim;                                     \
21204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   const unsigned max_count_simple = vsplit->segment_size;                 \
21304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   const unsigned max_count_loop = vsplit->segment_size - 1;               \
21404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   const unsigned max_count_fan = vsplit->segment_size;
21504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
216a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu#define PRIMITIVE(istart, icount)   \
217a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu   CONCAT(vsplit_primitive_, ELT_TYPE)(vsplit, istart, icount)
218a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu
21904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#else /* ELT_TYPE */
22004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
22104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wustatic void
22204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wuvsplit_segment_simple_linear(struct vsplit_frontend *vsplit, unsigned flags,
22304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                             unsigned istart, unsigned icount)
22404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu{
22504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   assert(icount <= vsplit->max_vertices);
22604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   vsplit->middle->run_linear(vsplit->middle, istart, icount, flags);
22704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu}
22804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
22904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wustatic void
23004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wuvsplit_segment_loop_linear(struct vsplit_frontend *vsplit, unsigned flags,
23104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                           unsigned istart, unsigned icount, unsigned i0)
23204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu{
23304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   boolean close_loop = (flags == DRAW_SPLIT_BEFORE);
23404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   unsigned nr;
23504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
23604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   assert(icount + !!close_loop <= vsplit->segment_size);
23704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
238b48e16fa2f8b96bb36a6e0a92b6d842c1c246006Brian Paul   /* need to draw the sections of the line loop as line strips */
239b48e16fa2f8b96bb36a6e0a92b6d842c1c246006Brian Paul   flags |= DRAW_LINE_LOOP_AS_STRIP;
240b48e16fa2f8b96bb36a6e0a92b6d842c1c246006Brian Paul
24104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   if (close_loop) {
24204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      for (nr = 0; nr < icount; nr++)
24304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         vsplit->fetch_elts[nr] = istart + nr;
24404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      vsplit->fetch_elts[nr++] = i0;
24504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
24604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      vsplit->middle->run(vsplit->middle, vsplit->fetch_elts, nr,
24704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            vsplit->identity_draw_elts, nr, flags);
24804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   }
24904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   else {
25004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      vsplit->middle->run_linear(vsplit->middle, istart, icount, flags);
25104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   }
25204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu}
25304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
25404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wustatic void
25504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wuvsplit_segment_fan_linear(struct vsplit_frontend *vsplit, unsigned flags,
25604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                          unsigned istart, unsigned icount, unsigned i0)
25704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu{
25804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   boolean use_spoken = ((flags & DRAW_SPLIT_BEFORE) != 0);
25904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   unsigned nr = 0, i;
26004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
261abbb1c8f084c6739bc9d6f559caf26f3f71b2fabChia-I Wu   assert(icount <= vsplit->segment_size);
26204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
26304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   if (use_spoken) {
264abbb1c8f084c6739bc9d6f559caf26f3f71b2fabChia-I Wu      /* replace istart by i0 */
26504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      vsplit->fetch_elts[nr++] = i0;
26604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      for (i = 1 ; i < icount; i++)
26704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         vsplit->fetch_elts[nr++] = istart + i;
26804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
26904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      vsplit->middle->run(vsplit->middle, vsplit->fetch_elts, nr,
27004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu            vsplit->identity_draw_elts, nr, flags);
27104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   }
27204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   else {
27304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      vsplit->middle->run_linear(vsplit->middle, istart, icount, flags);
27404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   }
27504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu}
27604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
27704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#define LOCAL_VARS                                                         \
27804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   struct vsplit_frontend *vsplit = (struct vsplit_frontend *) frontend;   \
27904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   const unsigned prim = vsplit->prim;                                     \
28004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   const unsigned max_count_simple = vsplit->max_vertices;                 \
28104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   const unsigned max_count_loop = vsplit->segment_size - 1;               \
28204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   const unsigned max_count_fan = vsplit->segment_size;
28304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
284a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu#define PRIMITIVE(istart, icount) FALSE
285a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu
28604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#define ELT_TYPE linear
28704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
28804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#endif /* ELT_TYPE */
28904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
29004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#define FUNC_VARS                      \
29104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   struct draw_pt_front_end *frontend, \
29204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   unsigned start,                     \
29304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   unsigned count
29404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
29504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#define SEGMENT_SIMPLE(flags, istart, icount)   \
29604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   CONCAT(vsplit_segment_simple_, ELT_TYPE)(vsplit, flags, istart, icount)
29704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
29804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#define SEGMENT_LOOP(flags, istart, icount, i0) \
29904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   CONCAT(vsplit_segment_loop_, ELT_TYPE)(vsplit, flags, istart, icount, i0)
30004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
30104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#define SEGMENT_FAN(flags, istart, icount, i0)  \
30204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   CONCAT(vsplit_segment_fan_, ELT_TYPE)(vsplit, flags, istart, icount, i0)
30304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
30404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#include "draw_split_tmp.h"
30504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
30604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#undef CONCAT2
30704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#undef CONCAT
30804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
30904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#undef ELT_TYPE
31004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#undef ADD_CACHE
311