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#include "c99_compat.h"
86
87static unsigned out_size_idx( unsigned index_size )
88{
89   switch (index_size) {
90   case 4: return OUT_UINT;
91   case 2: return OUT_USHORT;
92   default: assert(0); return OUT_USHORT;
93   }
94}
95
96static unsigned in_size_idx( unsigned index_size )
97{
98   switch (index_size) {
99   case 4: return IN_UINT;
100   case 2: return IN_USHORT;
101   case 1: return IN_UBYTE;
102   default: assert(0); return IN_UBYTE;
103   }
104}
105
106
107static u_translate_func translate[IN_COUNT][OUT_COUNT][PV_COUNT][PV_COUNT][PR_COUNT][PRIM_COUNT];
108static u_generate_func  generate[OUT_COUNT][PV_COUNT][PV_COUNT][PRIM_COUNT];
109
110
111''')
112
113def vert( intype, outtype, v0 ):
114    if intype == GENERATE:
115        return '(' + outtype + ')(' + v0 + ')'
116    else:
117        return '(' + outtype + ')in[' + v0 + ']'
118
119def point( intype, outtype, ptr, v0 ):
120    print('      (' + ptr + ')[0] = ' + vert( intype, outtype, v0 ) + ';')
121
122def line( intype, outtype, ptr, v0, v1 ):
123    print('      (' + ptr + ')[0] = ' + vert( intype, outtype, v0 ) + ';')
124    print('      (' + ptr + ')[1] = ' + vert( intype, outtype, v1 ) + ';')
125
126def tri( intype, outtype, ptr, v0, v1, v2 ):
127    print('      (' + ptr + ')[0] = ' + vert( intype, outtype, v0 ) + ';')
128    print('      (' + ptr + ')[1] = ' + vert( intype, outtype, v1 ) + ';')
129    print('      (' + ptr + ')[2] = ' + vert( intype, outtype, v2 ) + ';')
130
131def lineadj( intype, outtype, ptr, v0, v1, v2, v3 ):
132    print('      (' + ptr + ')[0] = ' + vert( intype, outtype, v0 ) + ';')
133    print('      (' + ptr + ')[1] = ' + vert( intype, outtype, v1 ) + ';')
134    print('      (' + ptr + ')[2] = ' + vert( intype, outtype, v2 ) + ';')
135    print('      (' + ptr + ')[3] = ' + vert( intype, outtype, v3 ) + ';')
136
137def triadj( intype, outtype, ptr, v0, v1, v2, v3, v4, v5 ):
138    print('      (' + ptr + ')[0] = ' + vert( intype, outtype, v0 ) + ';')
139    print('      (' + ptr + ')[1] = ' + vert( intype, outtype, v1 ) + ';')
140    print('      (' + ptr + ')[2] = ' + vert( intype, outtype, v2 ) + ';')
141    print('      (' + ptr + ')[3] = ' + vert( intype, outtype, v3 ) + ';')
142    print('      (' + ptr + ')[4] = ' + vert( intype, outtype, v4 ) + ';')
143    print('      (' + ptr + ')[5] = ' + vert( intype, outtype, v5 ) + ';')
144
145def do_point( intype, outtype, ptr, v0 ):
146    point( intype, outtype, ptr, v0 )
147
148def do_line( intype, outtype, ptr, v0, v1, inpv, outpv ):
149    if inpv == outpv:
150        line( intype, outtype, ptr, v0, v1 )
151    else:
152        line( intype, outtype, ptr, v1, v0 )
153
154def do_tri( intype, outtype, ptr, v0, v1, v2, inpv, outpv ):
155    if inpv == outpv:
156        tri( intype, outtype, ptr, v0, v1, v2 )
157    else:
158        if inpv == FIRST:
159            tri( intype, outtype, ptr, v1, v2, v0 )
160        else:
161            tri( intype, outtype, ptr, v2, v0, v1 )
162
163def do_quad( intype, outtype, ptr, v0, v1, v2, v3, inpv, outpv ):
164    if inpv == LAST:
165        do_tri( intype, outtype, ptr+'+0',  v0, v1, v3, inpv, outpv );
166        do_tri( intype, outtype, ptr+'+3',  v1, v2, v3, inpv, outpv );
167    else:
168        do_tri( intype, outtype, ptr+'+0',  v0, v1, v2, inpv, outpv );
169        do_tri( intype, outtype, ptr+'+3',  v0, v2, v3, inpv, outpv );
170
171def do_lineadj( intype, outtype, ptr, v0, v1, v2, v3, inpv, outpv ):
172    if inpv == outpv:
173        lineadj( intype, outtype, ptr, v0, v1, v2, v3 )
174    else:
175        lineadj( intype, outtype, ptr, v3, v2, v1, v0 )
176
177def do_triadj( intype, outtype, ptr, v0, v1, v2, v3, v4, v5, inpv, outpv ):
178    if inpv == outpv:
179        triadj( intype, outtype, ptr, v0, v1, v2, v3, v4, v5 )
180    else:
181        triadj( intype, outtype, ptr, v4, v5, v0, v1, v2, v3 )
182
183def name(intype, outtype, inpv, outpv, pr, prim):
184    if intype == GENERATE:
185        return 'generate_' + prim + '_' + outtype + '_' + inpv + '2' + outpv
186    else:
187        return 'translate_' + prim + '_' + intype + '2' + outtype + '_' + inpv + '2' + outpv + '_' + pr
188
189def preamble(intype, outtype, inpv, outpv, pr, prim):
190    print('static void ' + name( intype, outtype, inpv, outpv, pr, prim ) + '(')
191    if intype != GENERATE:
192        print('    const void * restrict _in,')
193    print('    unsigned start,')
194    if intype != GENERATE:
195        print('    unsigned in_nr,')
196    print('    unsigned out_nr,')
197    if intype != GENERATE:
198        print('    unsigned restart_index,')
199    print('    void * restrict _out )')
200    print('{')
201    if intype != GENERATE:
202        print('  const ' + intype + '* restrict in = (const ' + intype + '* restrict)_in;')
203    print('  ' + outtype + ' * restrict out = (' + outtype + '* restrict)_out;')
204    print('  unsigned i, j;')
205    print('  (void)j;')
206
207def postamble():
208    print('}')
209
210def prim_restart(in_verts, out_verts, out_prims, close_func = None):
211    print('restart:')
212    print('      if (i + ' + str(in_verts) + ' > in_nr) {')
213    for i in range(out_prims):
214        for j in range(out_verts):
215            print('         (out+j+' + str(out_verts * i) + ')[' + str(j) + '] = restart_index;')
216    print('         continue;')
217    print('      }')
218    for i in range(in_verts):
219        print('      if (in[i + ' + str(i) + '] == restart_index) {')
220        print('         i += ' + str(i + 1) + ';')
221
222        if close_func is not None:
223            close_func(i)
224
225        print('         goto restart;')
226        print('      }')
227
228def points(intype, outtype, inpv, outpv, pr):
229    preamble(intype, outtype, inpv, outpv, pr, prim='points')
230    print('  for (i = start, j = 0; j < out_nr; j++, i++) { ')
231    do_point( intype, outtype, 'out+j',  'i' );
232    print('   }')
233    postamble()
234
235def lines(intype, outtype, inpv, outpv, pr):
236    preamble(intype, outtype, inpv, outpv, pr, prim='lines')
237    print('  for (i = start, j = 0; j < out_nr; j+=2, i+=2) { ')
238    do_line( intype, outtype, 'out+j',  'i', 'i+1', inpv, outpv );
239    print('   }')
240    postamble()
241
242def linestrip(intype, outtype, inpv, outpv, pr):
243    preamble(intype, outtype, inpv, outpv, pr, prim='linestrip')
244    print('  for (i = start, j = 0; j < out_nr; j+=2, i++) { ')
245    do_line( intype, outtype, 'out+j',  'i', 'i+1', inpv, outpv );
246    print('   }')
247    postamble()
248
249def lineloop(intype, outtype, inpv, outpv, pr):
250    preamble(intype, outtype, inpv, outpv, pr, prim='lineloop')
251    print('  unsigned end = start;')
252    print('  for (i = start, j = 0; j < out_nr - 2; j+=2, i++) { ')
253    if pr == PRENABLE:
254        def close_func(index):
255            do_line( intype, outtype, 'out+j',  'end', 'start', inpv, outpv )
256            print('         start = i;')
257            print('         end = start;')
258            print('         j += 2;')
259
260        prim_restart(2, 2, 1, close_func)
261
262    do_line( intype, outtype, 'out+j',  'i', 'i+1', inpv, outpv );
263    print('      end = i+1;')
264    print('   }')
265    do_line( intype, outtype, 'out+j',  'end', 'start', inpv, outpv );
266    postamble()
267
268def tris(intype, outtype, inpv, outpv, pr):
269    preamble(intype, outtype, inpv, outpv, pr, prim='tris')
270    print('  for (i = start, j = 0; j < out_nr; j+=3, i+=3) { ')
271    do_tri( intype, outtype, 'out+j',  'i', 'i+1', 'i+2', inpv, outpv );
272    print('   }')
273    postamble()
274
275
276def tristrip(intype, outtype, inpv, outpv, pr):
277    preamble(intype, outtype, inpv, outpv, pr, prim='tristrip')
278    print('  for (i = start, j = 0; j < out_nr; j+=3, i++) { ')
279    if inpv == FIRST:
280        do_tri( intype, outtype, 'out+j',  'i', 'i+1+(i&1)', 'i+2-(i&1)', inpv, outpv );
281    else:
282        do_tri( intype, outtype, 'out+j',  'i+(i&1)', 'i+1-(i&1)', 'i+2', inpv, outpv );
283    print('   }')
284    postamble()
285
286
287def trifan(intype, outtype, inpv, outpv, pr):
288    preamble(intype, outtype, inpv, outpv, pr, prim='trifan')
289    print('  for (i = start, j = 0; j < out_nr; j+=3, i++) { ')
290
291    if pr == PRENABLE:
292        def close_func(index):
293            print('         start = i;')
294        prim_restart(3, 3, 1, close_func)
295
296    if inpv == FIRST:
297        do_tri( intype, outtype, 'out+j',  'i+1', 'i+2', 'start', inpv, outpv );
298    else:
299        do_tri( intype, outtype, 'out+j',  'start', 'i+1', 'i+2', inpv, outpv );
300
301    print('   }')
302    postamble()
303
304
305
306def polygon(intype, outtype, inpv, outpv, pr):
307    preamble(intype, outtype, inpv, outpv, pr, prim='polygon')
308    print('  for (i = start, j = 0; j < out_nr; j+=3, i++) { ')
309    if pr == PRENABLE:
310        def close_func(index):
311            print('         start = i;')
312        prim_restart(3, 3, 1, close_func)
313
314    if inpv == FIRST:
315        do_tri( intype, outtype, 'out+j',  'start', 'i+1', 'i+2', inpv, outpv );
316    else:
317        do_tri( intype, outtype, 'out+j',  'i+1', 'i+2', 'start', inpv, outpv );
318    print('   }')
319    postamble()
320
321
322def quads(intype, outtype, inpv, outpv, pr):
323    preamble(intype, outtype, inpv, outpv, pr, prim='quads')
324    print('  for (i = start, j = 0; j < out_nr; j+=6, i+=4) { ')
325    if pr == PRENABLE:
326        prim_restart(4, 3, 2)
327
328    do_quad( intype, outtype, 'out+j', 'i+0', 'i+1', 'i+2', 'i+3', inpv, outpv );
329    print('   }')
330    postamble()
331
332
333def quadstrip(intype, outtype, inpv, outpv, pr):
334    preamble(intype, outtype, inpv, outpv, pr, prim='quadstrip')
335    print('  for (i = start, j = 0; j < out_nr; j+=6, i+=2) { ')
336    if pr == PRENABLE:
337        prim_restart(4, 3, 2)
338
339    if inpv == LAST:
340        do_quad( intype, outtype, 'out+j', 'i+2', 'i+0', 'i+1', 'i+3', inpv, outpv );
341    else:
342        do_quad( intype, outtype, 'out+j', 'i+0', 'i+1', 'i+3', 'i+2', inpv, outpv );
343    print('   }')
344    postamble()
345
346
347def linesadj(intype, outtype, inpv, outpv, pr):
348    preamble(intype, outtype, inpv, outpv, pr, prim='linesadj')
349    print('  for (i = start, j = 0; j < out_nr; j+=4, i+=4) { ')
350    do_lineadj( intype, outtype, 'out+j',  'i+0', 'i+1', 'i+2', 'i+3', inpv, outpv )
351    print('  }')
352    postamble()
353
354
355def linestripadj(intype, outtype, inpv, outpv, pr):
356    preamble(intype, outtype, inpv, outpv, pr, prim='linestripadj')
357    print('  for (i = start, j = 0; j < out_nr; j+=4, i++) {')
358    do_lineadj( intype, outtype, 'out+j',  'i+0', 'i+1', 'i+2', 'i+3', inpv, outpv )
359    print('  }')
360    postamble()
361
362
363def trisadj(intype, outtype, inpv, outpv, pr):
364    preamble(intype, outtype, inpv, outpv, pr, prim='trisadj')
365    print('  for (i = start, j = 0; j < out_nr; j+=6, i+=6) { ')
366    do_triadj( intype, outtype, 'out+j',  'i+0', 'i+1', 'i+2', 'i+3',
367               'i+4', 'i+5', inpv, outpv )
368    print('  }')
369    postamble()
370
371
372def tristripadj(intype, outtype, inpv, outpv, pr):
373    preamble(intype, outtype, inpv, outpv, pr, prim='tristripadj')
374    print('  for (i = start, j = 0; j < out_nr; i+=2, j+=6) { ')
375    print('    if (i % 4 == 0) {')
376    print('      /* even triangle */')
377    do_triadj( intype, outtype, 'out+j',
378               'i+0', 'i+1', 'i+2', 'i+3', 'i+4', 'i+5', inpv, outpv )
379    print('    } else {')
380    print('      /* odd triangle */')
381    do_triadj( intype, outtype, 'out+j',
382               'i+2', 'i-2', 'i+0', 'i+3', 'i+4', 'i+6', inpv, outpv )
383    print('    }')
384    print('  }')
385    postamble()
386
387
388def emit_funcs():
389    for intype in INTYPES:
390        for outtype in OUTTYPES:
391            for inpv in (FIRST, LAST):
392                for outpv in (FIRST, LAST):
393                    for pr in (PRDISABLE, PRENABLE):
394                        if pr == PRENABLE and intype == GENERATE:
395                            continue
396                        points(intype, outtype, inpv, outpv, pr)
397                        lines(intype, outtype, inpv, outpv, pr)
398                        linestrip(intype, outtype, inpv, outpv, pr)
399                        lineloop(intype, outtype, inpv, outpv, pr)
400                        tris(intype, outtype, inpv, outpv, pr)
401                        tristrip(intype, outtype, inpv, outpv, pr)
402                        trifan(intype, outtype, inpv, outpv, pr)
403                        quads(intype, outtype, inpv, outpv, pr)
404                        quadstrip(intype, outtype, inpv, outpv, pr)
405                        polygon(intype, outtype, inpv, outpv, pr)
406                        linesadj(intype, outtype, inpv, outpv, pr)
407                        linestripadj(intype, outtype, inpv, outpv, pr)
408                        trisadj(intype, outtype, inpv, outpv, pr)
409                        tristripadj(intype, outtype, inpv, outpv, pr)
410
411def init(intype, outtype, inpv, outpv, pr, prim):
412    if intype == GENERATE:
413        print ('generate[' +
414               outtype_idx[outtype] +
415               '][' + pv_idx[inpv] +
416               '][' + pv_idx[outpv] +
417               '][' + longprim[prim] +
418               '] = ' + name( intype, outtype, inpv, outpv, pr, prim ) + ';')
419    else:
420        print ('translate[' +
421               intype_idx[intype] +
422               '][' + outtype_idx[outtype] +
423               '][' + pv_idx[inpv] +
424               '][' + pv_idx[outpv] +
425               '][' + pr_idx[pr] +
426               '][' + longprim[prim] +
427               '] = ' + name( intype, outtype, inpv, outpv, pr, prim ) + ';')
428
429
430def emit_all_inits():
431    for intype in INTYPES:
432        for outtype in OUTTYPES:
433            for inpv in PVS:
434                for outpv in PVS:
435                    for pr in PRS:
436                        for prim in PRIMS:
437                            init(intype, outtype, inpv, outpv, pr, prim)
438
439def emit_init():
440    print('void u_index_init( void )')
441    print('{')
442    print('  static int firsttime = 1;')
443    print('  if (!firsttime) return;')
444    print('  firsttime = 0;')
445    emit_all_inits()
446    print('}')
447
448
449
450
451def epilog():
452    print('#include "indices/u_indices.c"')
453
454
455def main():
456    prolog()
457    emit_funcs()
458    emit_init()
459    epilog()
460
461
462if __name__ == '__main__':
463    main()
464