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#include "util/u_math.h"
2704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#include "util/u_memory.h"
2804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
2904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#include "draw/draw_context.h"
3004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#include "draw/draw_private.h"
3104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#include "draw/draw_pt.h"
3204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
3304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#define SEGMENT_SIZE 1024
3404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#define MAP_SIZE     256
3504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
367a55c436c64a8bb031c8823522cde8f3adc67d89Roland Scheidegger/* The largest possible index within an index buffer */
37bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin#define MAX_ELT_IDX 0xffffffff
38bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin
3904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wustruct vsplit_frontend {
4004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   struct draw_pt_front_end base;
4104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   struct draw_context *draw;
4204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
4304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   unsigned prim;
4404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
4504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   struct draw_pt_middle_end *middle;
4604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
4704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   unsigned max_vertices;
4804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   ushort segment_size;
4904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
5004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   /* buffers for splitting */
5104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   unsigned fetch_elts[SEGMENT_SIZE];
5204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   ushort draw_elts[SEGMENT_SIZE];
5304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   ushort identity_draw_elts[SEGMENT_SIZE];
5404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
5504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   struct {
5604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      /* map a fetch element to a draw element */
5704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      unsigned fetches[MAP_SIZE];
5804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      ushort draws[MAP_SIZE];
5904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      boolean has_max_fetch;
6004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
6104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      ushort num_fetch_elts;
6204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      ushort num_draw_elts;
6304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   } cache;
6404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu};
6504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
6604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
6704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wustatic void
6804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wuvsplit_clear_cache(struct vsplit_frontend *vsplit)
6904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu{
7004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   memset(vsplit->cache.fetches, 0xff, sizeof(vsplit->cache.fetches));
7104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   vsplit->cache.has_max_fetch = FALSE;
7204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   vsplit->cache.num_fetch_elts = 0;
7304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   vsplit->cache.num_draw_elts = 0;
7404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu}
7504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
7604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wustatic void
7704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wuvsplit_flush_cache(struct vsplit_frontend *vsplit, unsigned flags)
7804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu{
7904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   vsplit->middle->run(vsplit->middle,
8004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         vsplit->fetch_elts, vsplit->cache.num_fetch_elts,
8104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu         vsplit->draw_elts, vsplit->cache.num_draw_elts, flags);
8204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu}
8304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
8404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu/**
8504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * Add a fetch element and add it to the draw elements.
8604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu */
87a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline void
8878a997f72841310620d18daa9015633343d04db1Roland Scheideggervsplit_add_cache(struct vsplit_frontend *vsplit, unsigned fetch)
8904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu{
903733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca   unsigned hash;
913733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca
923733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca   hash = fetch % MAP_SIZE;
9304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
942d5af04bae0668ce9e081f06f1dd4b25528e27e8Andres Gomez   /* If the value isn't in the cache or it's an overflow due to the
95bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin    * element bias */
9678a997f72841310620d18daa9015633343d04db1Roland Scheidegger   if (vsplit->cache.fetches[hash] != fetch) {
9704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      /* update cache */
9804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      vsplit->cache.fetches[hash] = fetch;
9904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      vsplit->cache.draws[hash] = vsplit->cache.num_fetch_elts;
10004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
10104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      /* add fetch */
10204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      assert(vsplit->cache.num_fetch_elts < vsplit->segment_size);
10304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      vsplit->fetch_elts[vsplit->cache.num_fetch_elts++] = fetch;
10404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   }
10504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
10604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   vsplit->draw_elts[vsplit->cache.num_draw_elts++] = vsplit->cache.draws[hash];
10704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu}
10804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
109bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin/**
110bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin * Returns the base index to the elements array.
11178a997f72841310620d18daa9015633343d04db1Roland Scheidegger * The value is checked for integer overflow (not sure it can happen?).
112bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin */
113a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline unsigned
1147a55c436c64a8bb031c8823522cde8f3adc67d89Roland Scheideggervsplit_get_base_idx(unsigned start, unsigned fetch)
115bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin{
1167a55c436c64a8bb031c8823522cde8f3adc67d89Roland Scheidegger   return draw_overflow_uadd(start, fetch, MAX_ELT_IDX);
117bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin}
118bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin
11978a997f72841310620d18daa9015633343d04db1Roland Scheidegger/*
12078a997f72841310620d18daa9015633343d04db1Roland Scheidegger * The final element index is just element index plus element bias.
121bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin */
122bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin#define VSPLIT_CREATE_IDX(elts, start, fetch, elt_bias)    \
123bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin   unsigned elt_idx;                                       \
12478a997f72841310620d18daa9015633343d04db1Roland Scheidegger   elt_idx = vsplit_get_base_idx(start, fetch);            \
12578a997f72841310620d18daa9015633343d04db1Roland Scheidegger   elt_idx = (unsigned)((int)(DRAW_GET_IDX(elts, elt_idx)) + (int)elt_bias);
12678a997f72841310620d18daa9015633343d04db1Roland Scheidegger
127bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin
128a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline void
129bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusinvsplit_add_cache_ubyte(struct vsplit_frontend *vsplit, const ubyte *elts,
130bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin                       unsigned start, unsigned fetch, int elt_bias)
131bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin{
132bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin   struct draw_context *draw = vsplit->draw;
133bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin   VSPLIT_CREATE_IDX(elts, start, fetch, elt_bias);
13478a997f72841310620d18daa9015633343d04db1Roland Scheidegger   /* unlike the uint case this can only happen with elt_bias */
13578a997f72841310620d18daa9015633343d04db1Roland Scheidegger   if (elt_bias && elt_idx == DRAW_MAX_FETCH_IDX && !vsplit->cache.has_max_fetch) {
13678a997f72841310620d18daa9015633343d04db1Roland Scheidegger      unsigned hash = fetch % MAP_SIZE;
13778a997f72841310620d18daa9015633343d04db1Roland Scheidegger      vsplit->cache.fetches[hash] = 0;
13878a997f72841310620d18daa9015633343d04db1Roland Scheidegger      vsplit->cache.has_max_fetch = TRUE;
13978a997f72841310620d18daa9015633343d04db1Roland Scheidegger   }
14078a997f72841310620d18daa9015633343d04db1Roland Scheidegger   vsplit_add_cache(vsplit, elt_idx);
141bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin}
142bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin
143a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline void
144bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusinvsplit_add_cache_ushort(struct vsplit_frontend *vsplit, const ushort *elts,
145bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin                       unsigned start, unsigned fetch, int elt_bias)
146bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin{
147bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin   struct draw_context *draw = vsplit->draw;
148bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin   VSPLIT_CREATE_IDX(elts, start, fetch, elt_bias);
14978a997f72841310620d18daa9015633343d04db1Roland Scheidegger   /* unlike the uint case this can only happen with elt_bias */
15078a997f72841310620d18daa9015633343d04db1Roland Scheidegger   if (elt_bias && elt_idx == DRAW_MAX_FETCH_IDX && !vsplit->cache.has_max_fetch) {
15178a997f72841310620d18daa9015633343d04db1Roland Scheidegger      unsigned hash = fetch % MAP_SIZE;
15278a997f72841310620d18daa9015633343d04db1Roland Scheidegger      vsplit->cache.fetches[hash] = 0;
15378a997f72841310620d18daa9015633343d04db1Roland Scheidegger      vsplit->cache.has_max_fetch = TRUE;
15478a997f72841310620d18daa9015633343d04db1Roland Scheidegger   }
15578a997f72841310620d18daa9015633343d04db1Roland Scheidegger   vsplit_add_cache(vsplit, elt_idx);
156bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin}
157bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin
15804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
15904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu/**
16004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * Add a fetch element and add it to the draw elements.  The fetch element is
16104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * in full range (uint).
16204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu */
163a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline void
164bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusinvsplit_add_cache_uint(struct vsplit_frontend *vsplit, const uint *elts,
165bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin                      unsigned start, unsigned fetch, int elt_bias)
16604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu{
167bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin   struct draw_context *draw = vsplit->draw;
168bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin   VSPLIT_CREATE_IDX(elts, start, fetch, elt_bias);
16978a997f72841310620d18daa9015633343d04db1Roland Scheidegger   /* Take care for DRAW_MAX_FETCH_IDX (since cache is initialized to -1). */
17078a997f72841310620d18daa9015633343d04db1Roland Scheidegger   if (elt_idx == DRAW_MAX_FETCH_IDX && !vsplit->cache.has_max_fetch) {
17104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      unsigned hash = fetch % MAP_SIZE;
17278a997f72841310620d18daa9015633343d04db1Roland Scheidegger      /* force update - any value will do except DRAW_MAX_FETCH_IDX */
17378a997f72841310620d18daa9015633343d04db1Roland Scheidegger      vsplit->cache.fetches[hash] = 0;
17404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      vsplit->cache.has_max_fetch = TRUE;
17504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   }
17678a997f72841310620d18daa9015633343d04db1Roland Scheidegger   vsplit_add_cache(vsplit, elt_idx);
17704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu}
17804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
17904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
18004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#define FUNC vsplit_run_linear
18104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#include "draw_pt_vsplit_tmp.h"
18204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
18304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#define FUNC vsplit_run_ubyte
18404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#define ELT_TYPE ubyte
185bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin#define ADD_CACHE(vsplit, ib, start, fetch, bias) vsplit_add_cache_ubyte(vsplit,ib,start,fetch,bias)
18604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#include "draw_pt_vsplit_tmp.h"
18704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
18804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#define FUNC vsplit_run_ushort
18904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#define ELT_TYPE ushort
190bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin#define ADD_CACHE(vsplit, ib, start, fetch, bias) vsplit_add_cache_ushort(vsplit,ib,start,fetch, bias)
19104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#include "draw_pt_vsplit_tmp.h"
19204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
19304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#define FUNC vsplit_run_uint
19404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#define ELT_TYPE uint
195bbd1e60198548a12be3405fc32dd39a87e8968abZack Rusin#define ADD_CACHE(vsplit, ib, start, fetch, bias) vsplit_add_cache_uint(vsplit, ib, start, fetch, bias)
19604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#include "draw_pt_vsplit_tmp.h"
19704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
19804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
19904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wustatic void vsplit_prepare(struct draw_pt_front_end *frontend,
20004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                           unsigned in_prim,
20104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                           struct draw_pt_middle_end *middle,
20204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu                           unsigned opt)
20304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu{
20404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   struct vsplit_frontend *vsplit = (struct vsplit_frontend *) frontend;
20504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
20604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   switch (vsplit->draw->pt.user.eltSize) {
20704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   case 0:
20804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      vsplit->base.run = vsplit_run_linear;
20904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      break;
21004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   case 1:
21104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      vsplit->base.run = vsplit_run_ubyte;
21204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      break;
21304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   case 2:
21404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      vsplit->base.run = vsplit_run_ushort;
21504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      break;
21604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   case 4:
21704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      vsplit->base.run = vsplit_run_uint;
21804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      break;
21904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   default:
22004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      assert(0);
22104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      break;
22204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   }
22304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
22404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   /* split only */
22504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   vsplit->prim = in_prim;
22604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
22704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   vsplit->middle = middle;
22804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   middle->prepare(middle, vsplit->prim, opt, &vsplit->max_vertices);
22904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
23004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   vsplit->segment_size = MIN2(SEGMENT_SIZE, vsplit->max_vertices);
23104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu}
23204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
23304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
234b6d3a435a0e0e53a9e8cc4c4249dc7c2f897a83dJakob Bornecrantzstatic void vsplit_flush(struct draw_pt_front_end *frontend, unsigned flags)
23504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu{
23604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   struct vsplit_frontend *vsplit = (struct vsplit_frontend *) frontend;
237b6d3a435a0e0e53a9e8cc4c4249dc7c2f897a83dJakob Bornecrantz
2384b73cdb864aef6d64c35a7ab9a59e4ee4e3f9d0fBrian Paul   if (flags & DRAW_FLUSH_STATE_CHANGE) {
239b6d3a435a0e0e53a9e8cc4c4249dc7c2f897a83dJakob Bornecrantz      vsplit->middle->finish(vsplit->middle);
240b6d3a435a0e0e53a9e8cc4c4249dc7c2f897a83dJakob Bornecrantz      vsplit->middle = NULL;
241b6d3a435a0e0e53a9e8cc4c4249dc7c2f897a83dJakob Bornecrantz   }
24204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu}
24304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
24404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
24504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wustatic void vsplit_destroy(struct draw_pt_front_end *frontend)
24604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu{
24704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   FREE(frontend);
24804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu}
24904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
25004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
25104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wustruct draw_pt_front_end *draw_pt_vsplit(struct draw_context *draw)
25204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu{
25304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   struct vsplit_frontend *vsplit = CALLOC_STRUCT(vsplit_frontend);
25404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   ushort i;
25504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
25604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   if (!vsplit)
25704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      return NULL;
25804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
25904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   vsplit->base.prepare = vsplit_prepare;
26004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   vsplit->base.run     = NULL;
261b6d3a435a0e0e53a9e8cc4c4249dc7c2f897a83dJakob Bornecrantz   vsplit->base.flush   = vsplit_flush;
26204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   vsplit->base.destroy = vsplit_destroy;
26304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   vsplit->draw = draw;
26404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
26504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   for (i = 0; i < SEGMENT_SIZE; i++)
26604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu      vsplit->identity_draw_elts[i] = i;
26704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu
26804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu   return &vsplit->base;
26904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu}
270