1copyright = '''
2/*
3 * Copyright 2009 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * on the rights to use, copy, modify, merge, publish, distribute, sub
10 * license, and/or sell copies of the Software, and to permit persons to whom
11 * the Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
20 * VMWARE AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23 * USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25'''
26
27GENERATE, UBYTE, USHORT, UINT = 'generate', 'ubyte', 'ushort', 'uint'
28FIRST, LAST = 'first', 'last'
29PRDISABLE, PRENABLE = 'prdisable', 'prenable'
30
31INTYPES = (GENERATE, UBYTE, USHORT, UINT)
32OUTTYPES = (USHORT, UINT)
33PVS=(FIRST, LAST)
34PRS=(PRDISABLE, PRENABLE)
35PRIMS=('points',
36       'lines',
37       'linestrip',
38       'lineloop',
39       'tris',
40       'trifan',
41       'tristrip',
42       'quads',
43       'quadstrip',
44       'polygon',
45       'linesadj',
46       'linestripadj',
47       'trisadj',
48       'tristripadj')
49
50LONGPRIMS=('PIPE_PRIM_POINTS',
51           'PIPE_PRIM_LINES',
52           'PIPE_PRIM_LINE_STRIP',
53           'PIPE_PRIM_LINE_LOOP',
54           'PIPE_PRIM_TRIANGLES',
55           'PIPE_PRIM_TRIANGLE_FAN',
56           'PIPE_PRIM_TRIANGLE_STRIP',
57           'PIPE_PRIM_QUADS',
58           'PIPE_PRIM_QUAD_STRIP',
59           'PIPE_PRIM_POLYGON',
60           'PIPE_PRIM_LINES_ADJACENCY',
61           'PIPE_PRIM_LINE_STRIP_ADJACENCY',
62           'PIPE_PRIM_TRIANGLES_ADJACENCY',
63           'PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY')
64
65longprim = dict(zip(PRIMS, LONGPRIMS))
66intype_idx = dict(ubyte='IN_UBYTE', ushort='IN_USHORT', uint='IN_UINT')
67outtype_idx = dict(ushort='OUT_USHORT', uint='OUT_UINT')
68pv_idx = dict(first='PV_FIRST', last='PV_LAST')
69pr_idx = dict(prdisable='PR_DISABLE', prenable='PR_ENABLE')
70
71def prolog():
72    print('''/* File automatically generated by u_indices_gen.py */''')
73    print(copyright)
74    print(r'''
75
76/**
77 * @file
78 * Functions to translate and generate index lists
79 */
80
81#include "indices/u_indices_priv.h"
82#include "util/u_debug.h"
83#include "util/u_memory.h"
84
85
86static unsigned out_size_idx( unsigned index_size )
87{
88   switch (index_size) {
89   case 4: return OUT_UINT;
90   case 2: return OUT_USHORT;
91   default: assert(0); return OUT_USHORT;
92   }
93}
94
95static unsigned in_size_idx( unsigned index_size )
96{
97   switch (index_size) {
98   case 4: return IN_UINT;
99   case 2: return IN_USHORT;
100   case 1: return IN_UBYTE;
101   default: assert(0); return IN_UBYTE;
102   }
103}
104
105
106static u_translate_func translate[IN_COUNT][OUT_COUNT][PV_COUNT][PV_COUNT][PR_COUNT][PRIM_COUNT];
107static u_generate_func  generate[OUT_COUNT][PV_COUNT][PV_COUNT][PRIM_COUNT];
108
109
110''')
111
112def vert( intype, outtype, v0 ):
113    if intype == GENERATE:
114        return '(' + outtype + ')(' + v0 + ')'
115    else:
116        return '(' + outtype + ')in[' + v0 + ']'
117
118def point( intype, outtype, ptr, v0 ):
119    print('      (' + ptr + ')[0] = ' + vert( intype, outtype, v0 ) + ';')
120
121def line( intype, outtype, ptr, v0, v1 ):
122    print('      (' + ptr + ')[0] = ' + vert( intype, outtype, v0 ) + ';')
123    print('      (' + ptr + ')[1] = ' + vert( intype, outtype, v1 ) + ';')
124
125def tri( intype, outtype, ptr, v0, v1, v2 ):
126    print('      (' + ptr + ')[0] = ' + vert( intype, outtype, v0 ) + ';')
127    print('      (' + ptr + ')[1] = ' + vert( intype, outtype, v1 ) + ';')
128    print('      (' + ptr + ')[2] = ' + vert( intype, outtype, v2 ) + ';')
129
130def lineadj( intype, outtype, ptr, v0, v1, v2, v3 ):
131    print('      (' + ptr + ')[0] = ' + vert( intype, outtype, v0 ) + ';')
132    print('      (' + ptr + ')[1] = ' + vert( intype, outtype, v1 ) + ';')
133    print('      (' + ptr + ')[2] = ' + vert( intype, outtype, v2 ) + ';')
134    print('      (' + ptr + ')[3] = ' + vert( intype, outtype, v3 ) + ';')
135
136def triadj( intype, outtype, ptr, v0, v1, v2, v3, v4, v5 ):
137    print('      (' + ptr + ')[0] = ' + vert( intype, outtype, v0 ) + ';')
138    print('      (' + ptr + ')[1] = ' + vert( intype, outtype, v1 ) + ';')
139    print('      (' + ptr + ')[2] = ' + vert( intype, outtype, v2 ) + ';')
140    print('      (' + ptr + ')[3] = ' + vert( intype, outtype, v3 ) + ';')
141    print('      (' + ptr + ')[4] = ' + vert( intype, outtype, v4 ) + ';')
142    print('      (' + ptr + ')[5] = ' + vert( intype, outtype, v5 ) + ';')
143
144def do_point( intype, outtype, ptr, v0 ):
145    point( intype, outtype, ptr, v0 )
146
147def do_line( intype, outtype, ptr, v0, v1, inpv, outpv ):
148    if inpv == outpv:
149        line( intype, outtype, ptr, v0, v1 )
150    else:
151        line( intype, outtype, ptr, v1, v0 )
152
153def do_tri( intype, outtype, ptr, v0, v1, v2, inpv, outpv ):
154    if inpv == outpv:
155        tri( intype, outtype, ptr, v0, v1, v2 )
156    else:
157        if inpv == FIRST:
158            tri( intype, outtype, ptr, v1, v2, v0 )
159        else:
160            tri( intype, outtype, ptr, v2, v0, v1 )
161
162def do_quad( intype, outtype, ptr, v0, v1, v2, v3, inpv, outpv ):
163    if inpv == LAST:
164        do_tri( intype, outtype, ptr+'+0',  v0, v1, v3, inpv, outpv );
165        do_tri( intype, outtype, ptr+'+3',  v1, v2, v3, inpv, outpv );
166    else:
167        do_tri( intype, outtype, ptr+'+0',  v0, v1, v2, inpv, outpv );
168        do_tri( intype, outtype, ptr+'+3',  v0, v2, v3, inpv, outpv );
169
170def do_lineadj( intype, outtype, ptr, v0, v1, v2, v3, inpv, outpv ):
171    if inpv == outpv:
172        lineadj( intype, outtype, ptr, v0, v1, v2, v3 )
173    else:
174        lineadj( intype, outtype, ptr, v3, v2, v1, v0 )
175
176def do_triadj( intype, outtype, ptr, v0, v1, v2, v3, v4, v5, inpv, outpv ):
177    if inpv == outpv:
178        triadj( intype, outtype, ptr, v0, v1, v2, v3, v4, v5 )
179    else:
180        triadj( intype, outtype, ptr, v4, v5, v0, v1, v2, v3 )
181
182def name(intype, outtype, inpv, outpv, pr, prim):
183    if intype == GENERATE:
184        return 'generate_' + prim + '_' + outtype + '_' + inpv + '2' + outpv
185    else:
186        return 'translate_' + prim + '_' + intype + '2' + outtype + '_' + inpv + '2' + outpv + '_' + pr
187
188def preamble(intype, outtype, inpv, outpv, pr, prim):
189    print('static void ' + name( intype, outtype, inpv, outpv, pr, prim ) + '(')
190    if intype != GENERATE:
191        print('    const void * restrict _in,')
192    print('    unsigned start,')
193    if intype != GENERATE:
194        print('    unsigned in_nr,')
195    print('    unsigned out_nr,')
196    if intype != GENERATE:
197        print('    unsigned restart_index,')
198    print('    void * restrict _out )')
199    print('{')
200    if intype != GENERATE:
201        print('  const ' + intype + '* restrict in = (const ' + intype + '* restrict)_in;')
202    print('  ' + outtype + ' * restrict out = (' + outtype + '* restrict)_out;')
203    print('  unsigned i, j;')
204    print('  (void)j;')
205
206def postamble():
207    print('}')
208
209def prim_restart(in_verts, out_verts, out_prims, close_func = None):
210    print('restart:')
211    print('      if (i + ' + str(in_verts) + ' > in_nr) {')
212    for i in range(out_prims):
213        for j in range(out_verts):
214            print('         (out+j+' + str(out_verts * i) + ')[' + str(j) + '] = restart_index;')
215    print('         continue;')
216    print('      }')
217    for i in range(in_verts):
218        print('      if (in[i + ' + str(i) + '] == restart_index) {')
219        print('         i += ' + str(i + 1) + ';')
220
221        if close_func is not None:
222            close_func(i)
223
224        print('         goto restart;')
225        print('      }')
226
227def points(intype, outtype, inpv, outpv, pr):
228    preamble(intype, outtype, inpv, outpv, pr, prim='points')
229    print('  for (i = start, j = 0; j < out_nr; j++, i++) { ')
230    do_point( intype, outtype, 'out+j',  'i' );
231    print('   }')
232    postamble()
233
234def lines(intype, outtype, inpv, outpv, pr):
235    preamble(intype, outtype, inpv, outpv, pr, prim='lines')
236    print('  for (i = start, j = 0; j < out_nr; j+=2, i+=2) { ')
237    do_line( intype, outtype, 'out+j',  'i', 'i+1', inpv, outpv );
238    print('   }')
239    postamble()
240
241def linestrip(intype, outtype, inpv, outpv, pr):
242    preamble(intype, outtype, inpv, outpv, pr, prim='linestrip')
243    print('  for (i = start, j = 0; j < out_nr; j+=2, i++) { ')
244    do_line( intype, outtype, 'out+j',  'i', 'i+1', inpv, outpv );
245    print('   }')
246    postamble()
247
248def lineloop(intype, outtype, inpv, outpv, pr):
249    preamble(intype, outtype, inpv, outpv, pr, prim='lineloop')
250    print('  unsigned end = start;')
251    print('  for (i = start, j = 0; j < out_nr - 2; j+=2, i++) { ')
252    if pr == PRENABLE:
253        def close_func(index):
254            do_line( intype, outtype, 'out+j',  'end', 'start', inpv, outpv )
255            print('         start = i;')
256            print('         end = start;')
257            print('         j += 2;')
258
259        prim_restart(2, 2, 1, close_func)
260
261    do_line( intype, outtype, 'out+j',  'i', 'i+1', inpv, outpv );
262    print('      end = i+1;')
263    print('   }')
264    do_line( intype, outtype, 'out+j',  'end', 'start', inpv, outpv );
265    postamble()
266
267def tris(intype, outtype, inpv, outpv, pr):
268    preamble(intype, outtype, inpv, outpv, pr, prim='tris')
269    print('  for (i = start, j = 0; j < out_nr; j+=3, i+=3) { ')
270    do_tri( intype, outtype, 'out+j',  'i', 'i+1', 'i+2', inpv, outpv );
271    print('   }')
272    postamble()
273
274
275def tristrip(intype, outtype, inpv, outpv, pr):
276    preamble(intype, outtype, inpv, outpv, pr, prim='tristrip')
277    print('  for (i = start, j = 0; j < out_nr; j+=3, i++) { ')
278    if inpv == FIRST:
279        do_tri( intype, outtype, 'out+j',  'i', 'i+1+(i&1)', 'i+2-(i&1)', inpv, outpv );
280    else:
281        do_tri( intype, outtype, 'out+j',  'i+(i&1)', 'i+1-(i&1)', 'i+2', inpv, outpv );
282    print('   }')
283    postamble()
284
285
286def trifan(intype, outtype, inpv, outpv, pr):
287    preamble(intype, outtype, inpv, outpv, pr, prim='trifan')
288    print('  for (i = start, j = 0; j < out_nr; j+=3, i++) { ')
289
290    if pr == PRENABLE:
291        def close_func(index):
292            print('         start = i;')
293        prim_restart(3, 3, 1, close_func)
294
295    if inpv == FIRST:
296        do_tri( intype, outtype, 'out+j',  'i+1', 'i+2', 'start', inpv, outpv );
297    else:
298        do_tri( intype, outtype, 'out+j',  'start', 'i+1', 'i+2', inpv, outpv );
299
300    print('   }')
301    postamble()
302
303
304
305def polygon(intype, outtype, inpv, outpv, pr):
306    preamble(intype, outtype, inpv, outpv, pr, prim='polygon')
307    print('  for (i = start, j = 0; j < out_nr; j+=3, i++) { ')
308    if pr == PRENABLE:
309        def close_func(index):
310            print('         start = i;')
311        prim_restart(3, 3, 1, close_func)
312
313    if inpv == FIRST:
314        do_tri( intype, outtype, 'out+j',  'start', 'i+1', 'i+2', inpv, outpv );
315    else:
316        do_tri( intype, outtype, 'out+j',  'i+1', 'i+2', 'start', inpv, outpv );
317    print('   }')
318    postamble()
319
320
321def quads(intype, outtype, inpv, outpv, pr):
322    preamble(intype, outtype, inpv, outpv, pr, prim='quads')
323    print('  for (i = start, j = 0; j < out_nr; j+=6, i+=4) { ')
324    if pr == PRENABLE:
325        prim_restart(4, 3, 2)
326
327    do_quad( intype, outtype, 'out+j', 'i+0', 'i+1', 'i+2', 'i+3', inpv, outpv );
328    print('   }')
329    postamble()
330
331
332def quadstrip(intype, outtype, inpv, outpv, pr):
333    preamble(intype, outtype, inpv, outpv, pr, prim='quadstrip')
334    print('  for (i = start, j = 0; j < out_nr; j+=6, i+=2) { ')
335    if pr == PRENABLE:
336        prim_restart(4, 3, 2)
337
338    if inpv == LAST:
339        do_quad( intype, outtype, 'out+j', 'i+2', 'i+0', 'i+1', 'i+3', inpv, outpv );
340    else:
341        do_quad( intype, outtype, 'out+j', 'i+0', 'i+1', 'i+3', 'i+2', inpv, outpv );
342    print('   }')
343    postamble()
344
345
346def linesadj(intype, outtype, inpv, outpv, pr):
347    preamble(intype, outtype, inpv, outpv, pr, prim='linesadj')
348    print('  for (i = start, j = 0; j < out_nr; j+=4, i+=4) { ')
349    do_lineadj( intype, outtype, 'out+j',  'i+0', 'i+1', 'i+2', 'i+3', inpv, outpv )
350    print('  }')
351    postamble()
352
353
354def linestripadj(intype, outtype, inpv, outpv, pr):
355    preamble(intype, outtype, inpv, outpv, pr, prim='linestripadj')
356    print('  for (i = start, j = 0; j < out_nr; j+=4, i++) {')
357    do_lineadj( intype, outtype, 'out+j',  'i+0', 'i+1', 'i+2', 'i+3', inpv, outpv )
358    print('  }')
359    postamble()
360
361
362def trisadj(intype, outtype, inpv, outpv, pr):
363    preamble(intype, outtype, inpv, outpv, pr, prim='trisadj')
364    print('  for (i = start, j = 0; j < out_nr; j+=6, i+=6) { ')
365    do_triadj( intype, outtype, 'out+j',  'i+0', 'i+1', 'i+2', 'i+3',
366               'i+4', 'i+5', inpv, outpv )
367    print('  }')
368    postamble()
369
370
371def tristripadj(intype, outtype, inpv, outpv, pr):
372    preamble(intype, outtype, inpv, outpv, pr, prim='tristripadj')
373    print('  for (i = start, j = 0; j < out_nr; i+=2, j+=6) { ')
374    print('    if (i % 4 == 0) {')
375    print('      /* even triangle */')
376    do_triadj( intype, outtype, 'out+j',
377               'i+0', 'i+1', 'i+2', 'i+3', 'i+4', 'i+5', inpv, outpv )
378    print('    } else {')
379    print('      /* odd triangle */')
380    do_triadj( intype, outtype, 'out+j',
381               'i+2', 'i-2', 'i+0', 'i+3', 'i+4', 'i+6', inpv, outpv )
382    print('    }')
383    print('  }')
384    postamble()
385
386
387def emit_funcs():
388    for intype in INTYPES:
389        for outtype in OUTTYPES:
390            for inpv in (FIRST, LAST):
391                for outpv in (FIRST, LAST):
392                    for pr in (PRDISABLE, PRENABLE):
393                        if pr == PRENABLE and intype == GENERATE:
394                            continue
395                        points(intype, outtype, inpv, outpv, pr)
396                        lines(intype, outtype, inpv, outpv, pr)
397                        linestrip(intype, outtype, inpv, outpv, pr)
398                        lineloop(intype, outtype, inpv, outpv, pr)
399                        tris(intype, outtype, inpv, outpv, pr)
400                        tristrip(intype, outtype, inpv, outpv, pr)
401                        trifan(intype, outtype, inpv, outpv, pr)
402                        quads(intype, outtype, inpv, outpv, pr)
403                        quadstrip(intype, outtype, inpv, outpv, pr)
404                        polygon(intype, outtype, inpv, outpv, pr)
405                        linesadj(intype, outtype, inpv, outpv, pr)
406                        linestripadj(intype, outtype, inpv, outpv, pr)
407                        trisadj(intype, outtype, inpv, outpv, pr)
408                        tristripadj(intype, outtype, inpv, outpv, pr)
409
410def init(intype, outtype, inpv, outpv, pr, prim):
411    if intype == GENERATE:
412        print ('generate[' +
413               outtype_idx[outtype] +
414               '][' + pv_idx[inpv] +
415               '][' + pv_idx[outpv] +
416               '][' + longprim[prim] +
417               '] = ' + name( intype, outtype, inpv, outpv, pr, prim ) + ';')
418    else:
419        print ('translate[' +
420               intype_idx[intype] +
421               '][' + outtype_idx[outtype] +
422               '][' + pv_idx[inpv] +
423               '][' + pv_idx[outpv] +
424               '][' + pr_idx[pr] +
425               '][' + longprim[prim] +
426               '] = ' + name( intype, outtype, inpv, outpv, pr, prim ) + ';')
427
428
429def emit_all_inits():
430    for intype in INTYPES:
431        for outtype in OUTTYPES:
432            for inpv in PVS:
433                for outpv in PVS:
434                    for pr in PRS:
435                        for prim in PRIMS:
436                            init(intype, outtype, inpv, outpv, pr, prim)
437
438def emit_init():
439    print('void u_index_init( void )')
440    print('{')
441    print('  static int firsttime = 1;')
442    print('  if (!firsttime) return;')
443    print('  firsttime = 0;')
444    emit_all_inits()
445    print('}')
446
447
448
449
450def epilog():
451    print('#include "indices/u_indices.c"')
452
453
454def main():
455    prolog()
456    emit_funcs()
457    emit_init()
458    epilog()
459
460
461if __name__ == '__main__':
462    main()
463