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 * _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 *_out )'
199    print '{'
200    if intype != GENERATE:
201        print '  const ' + intype + '*in = (const ' + intype + '*)_in;'
202    print '  ' + outtype + ' *out = (' + outtype + '*)_out;'
203    print '  unsigned i, j;'
204    print '  (void)j;'
205
206def postamble():
207    print '}'
208
209
210def points(intype, outtype, inpv, outpv, pr):
211    preamble(intype, outtype, inpv, outpv, pr, prim='points')
212    print '  for (i = start; i < (out_nr+start); i++) { '
213    do_point( intype, outtype, 'out+i',  'i' );
214    print '   }'
215    postamble()
216
217def lines(intype, outtype, inpv, outpv, pr):
218    preamble(intype, outtype, inpv, outpv, pr, prim='lines')
219    print '  for (i = start; i < (out_nr+start); i+=2) { '
220    do_line( intype, outtype, 'out+i',  'i', 'i+1', inpv, outpv );
221    print '   }'
222    postamble()
223
224def linestrip(intype, outtype, inpv, outpv, pr):
225    preamble(intype, outtype, inpv, outpv, pr, prim='linestrip')
226    print '  for (i = start, j = 0; j < out_nr; j+=2, i++) { '
227    do_line( intype, outtype, 'out+j',  'i', 'i+1', inpv, outpv );
228    print '   }'
229    postamble()
230
231def lineloop(intype, outtype, inpv, outpv, pr):
232    preamble(intype, outtype, inpv, outpv, pr, prim='lineloop')
233    print '  for (i = start, j = 0; j < out_nr - 2; j+=2, i++) { '
234    do_line( intype, outtype, 'out+j',  'i', 'i+1', inpv, outpv );
235    print '   }'
236    do_line( intype, outtype, 'out+j',  'i', 'start', inpv, outpv );
237    postamble()
238
239def tris(intype, outtype, inpv, outpv, pr):
240    preamble(intype, outtype, inpv, outpv, pr, prim='tris')
241    print '  for (i = start; i < (out_nr+start); i+=3) { '
242    do_tri( intype, outtype, 'out+i',  'i', 'i+1', 'i+2', inpv, outpv );
243    print '   }'
244    postamble()
245
246
247def tristrip(intype, outtype, inpv, outpv, pr):
248    preamble(intype, outtype, inpv, outpv, pr, prim='tristrip')
249    print '  for (i = start, j = 0; j < out_nr; j+=3, i++) { '
250    if inpv == FIRST:
251        do_tri( intype, outtype, 'out+j',  'i', 'i+1+(i&1)', 'i+2-(i&1)', inpv, outpv );
252    else:
253        do_tri( intype, outtype, 'out+j',  'i+(i&1)', 'i+1-(i&1)', 'i+2', inpv, outpv );
254    print '   }'
255    postamble()
256
257
258def trifan(intype, outtype, inpv, outpv, pr):
259    preamble(intype, outtype, inpv, outpv, pr, prim='trifan')
260    print '  for (i = start, j = 0; j < out_nr; j+=3, i++) { '
261    do_tri( intype, outtype, 'out+j',  'start', 'i+1', 'i+2', inpv, outpv );
262    print '   }'
263    postamble()
264
265
266
267def polygon(intype, outtype, inpv, outpv, pr):
268    preamble(intype, outtype, inpv, outpv, pr, prim='polygon')
269    print '  for (i = start, j = 0; j < out_nr; j+=3, i++) { '
270    if pr == PRENABLE:
271        print 'restart:'
272        print '      if (i + 3 > in_nr) {'
273        print '         (out+j+0)[0] = restart_index;'
274        print '         (out+j+0)[1] = restart_index;'
275        print '         (out+j+0)[2] = restart_index;'
276        print '         continue;'
277        print '      }'
278        print '      if (in[i + 0] == restart_index) {'
279        print '         i += 1;'
280        print '         start = i;'
281        print '         goto restart;'
282        print '      }'
283        print '      if (in[i + 1] == restart_index) {'
284        print '         i += 2;'
285        print '         start = i;'
286        print '         goto restart;'
287        print '      }'
288        print '      if (in[i + 2] == restart_index) {'
289        print '         i += 3;'
290        print '         start = i;'
291        print '         goto restart;'
292        print '      }'
293
294    if inpv == FIRST:
295        do_tri( intype, outtype, 'out+j',  'start', 'i+1', 'i+2', inpv, outpv );
296    else:
297        do_tri( intype, outtype, 'out+j',  'i+1', 'i+2', 'start', inpv, outpv );
298    print '   }'
299    postamble()
300
301
302def quads(intype, outtype, inpv, outpv, pr):
303    preamble(intype, outtype, inpv, outpv, pr, prim='quads')
304    print '  for (i = start, j = 0; j < out_nr; j+=6, i+=4) { '
305    if pr == PRENABLE:
306        print 'restart:'
307        print '      if (i + 4 > in_nr) {'
308        print '         (out+j+0)[0] = restart_index;'
309        print '         (out+j+0)[1] = restart_index;'
310        print '         (out+j+0)[2] = restart_index;'
311        print '         (out+j+3)[0] = restart_index;'
312        print '         (out+j+3)[1] = restart_index;'
313        print '         (out+j+3)[2] = restart_index;'
314        print '         continue;'
315        print '      }'
316        print '      if (in[i + 0] == restart_index) {'
317        print '         i += 1;'
318        print '         goto restart;'
319        print '      }'
320        print '      if (in[i + 1] == restart_index) {'
321        print '         i += 2;'
322        print '         goto restart;'
323        print '      }'
324        print '      if (in[i + 2] == restart_index) {'
325        print '         i += 3;'
326        print '         goto restart;'
327        print '      }'
328        print '      if (in[i + 3] == restart_index) {'
329        print '         i += 4;'
330        print '         goto restart;'
331        print '      }'
332
333    do_quad( intype, outtype, 'out+j', 'i+0', 'i+1', 'i+2', 'i+3', inpv, outpv );
334    print '   }'
335    postamble()
336
337
338def quadstrip(intype, outtype, inpv, outpv, pr):
339    preamble(intype, outtype, inpv, outpv, pr, prim='quadstrip')
340    print '  for (i = start, j = 0; j < out_nr; j+=6, i+=2) { '
341    if pr == PRENABLE:
342        print 'restart:'
343        print '      if (i + 4 > in_nr) {'
344        print '         (out+j+0)[0] = restart_index;'
345        print '         (out+j+0)[1] = restart_index;'
346        print '         (out+j+0)[2] = restart_index;'
347        print '         (out+j+3)[0] = restart_index;'
348        print '         (out+j+3)[1] = restart_index;'
349        print '         (out+j+3)[2] = restart_index;'
350        print '         continue;'
351        print '      }'
352        print '      if (in[i + 0] == restart_index) {'
353        print '         i += 1;'
354        print '         goto restart;'
355        print '      }'
356        print '      if (in[i + 1] == restart_index) {'
357        print '         i += 2;'
358        print '         goto restart;'
359        print '      }'
360        print '      if (in[i + 2] == restart_index) {'
361        print '         i += 3;'
362        print '         goto restart;'
363        print '      }'
364        print '      if (in[i + 3] == restart_index) {'
365        print '         i += 4;'
366        print '         goto restart;'
367        print '      }'
368    if inpv == LAST:
369        do_quad( intype, outtype, 'out+j', 'i+2', 'i+0', 'i+1', 'i+3', inpv, outpv );
370    else:
371        do_quad( intype, outtype, 'out+j', 'i+0', 'i+1', 'i+3', 'i+2', inpv, outpv );
372    print '   }'
373    postamble()
374
375
376def linesadj(intype, outtype, inpv, outpv, pr):
377    preamble(intype, outtype, inpv, outpv, pr, prim='linesadj')
378    print '  for (i = start; i < (out_nr+start); i+=4) { '
379    do_lineadj( intype, outtype, 'out+i',  'i+0', 'i+1', 'i+2', 'i+3', inpv, outpv )
380    print '  }'
381    postamble()
382
383
384def linestripadj(intype, outtype, inpv, outpv, pr):
385    preamble(intype, outtype, inpv, outpv, pr, prim='linestripadj')
386    print '  for (i = start, j = 0; j < out_nr; j+=4, i++) {'
387    do_lineadj( intype, outtype, 'out+j',  'i+0', 'i+1', 'i+2', 'i+3', inpv, outpv )
388    print '  }'
389    postamble()
390
391
392def trisadj(intype, outtype, inpv, outpv, pr):
393    preamble(intype, outtype, inpv, outpv, pr, prim='trisadj')
394    print '  for (i = start; i < (out_nr+start); i+=6) { '
395    do_triadj( intype, outtype, 'out+i',  'i+0', 'i+1', 'i+2', 'i+3',
396               'i+4', 'i+5', inpv, outpv )
397    print '  }'
398    postamble()
399
400
401def tristripadj(intype, outtype, inpv, outpv, pr):
402    preamble(intype, outtype, inpv, outpv, pr, prim='tristripadj')
403    print '  for (i = start, j = 0; j < out_nr; i+=2, j+=6) { '
404    print '    if (i % 4 == 0) {'
405    print '      /* even triangle */'
406    do_triadj( intype, outtype, 'out+j',
407               'i+0', 'i+1', 'i+2', 'i+3', 'i+4', 'i+5', inpv, outpv )
408    print '    } else {'
409    print '      /* odd triangle */'
410    do_triadj( intype, outtype, 'out+j',
411               'i+2', 'i-2', 'i+0', 'i+3', 'i+4', 'i+6', inpv, outpv )
412    print '    }'
413    print '  }'
414    postamble()
415
416
417def emit_funcs():
418    for intype in INTYPES:
419        for outtype in OUTTYPES:
420            for inpv in (FIRST, LAST):
421                for outpv in (FIRST, LAST):
422                    for pr in (PRDISABLE, PRENABLE):
423                        if pr == PRENABLE and intype == GENERATE:
424                            continue
425                        points(intype, outtype, inpv, outpv, pr)
426                        lines(intype, outtype, inpv, outpv, pr)
427                        linestrip(intype, outtype, inpv, outpv, pr)
428                        lineloop(intype, outtype, inpv, outpv, pr)
429                        tris(intype, outtype, inpv, outpv, pr)
430                        tristrip(intype, outtype, inpv, outpv, pr)
431                        trifan(intype, outtype, inpv, outpv, pr)
432                        quads(intype, outtype, inpv, outpv, pr)
433                        quadstrip(intype, outtype, inpv, outpv, pr)
434                        polygon(intype, outtype, inpv, outpv, pr)
435                        linesadj(intype, outtype, inpv, outpv, pr)
436                        linestripadj(intype, outtype, inpv, outpv, pr)
437                        trisadj(intype, outtype, inpv, outpv, pr)
438                        tristripadj(intype, outtype, inpv, outpv, pr)
439
440def init(intype, outtype, inpv, outpv, pr, prim):
441    if intype == GENERATE:
442        print ('generate[' +
443               outtype_idx[outtype] +
444               '][' + pv_idx[inpv] +
445               '][' + pv_idx[outpv] +
446               '][' + longprim[prim] +
447               '] = ' + name( intype, outtype, inpv, outpv, pr, prim ) + ';')
448    else:
449        print ('translate[' +
450               intype_idx[intype] +
451               '][' + outtype_idx[outtype] +
452               '][' + pv_idx[inpv] +
453               '][' + pv_idx[outpv] +
454               '][' + pr_idx[pr] +
455               '][' + longprim[prim] +
456               '] = ' + name( intype, outtype, inpv, outpv, pr, prim ) + ';')
457
458
459def emit_all_inits():
460    for intype in INTYPES:
461        for outtype in OUTTYPES:
462            for inpv in PVS:
463                for outpv in PVS:
464                    for pr in PRS:
465                        for prim in PRIMS:
466                            init(intype, outtype, inpv, outpv, pr, prim)
467
468def emit_init():
469    print 'void u_index_init( void )'
470    print '{'
471    print '  static int firsttime = 1;'
472    print '  if (!firsttime) return;'
473    print '  firsttime = 0;'
474    emit_all_inits()
475    print '}'
476
477
478
479
480def epilog():
481    print '#include "indices/u_indices.c"'
482
483
484def main():
485    prolog()
486    emit_funcs()
487    emit_init()
488    epilog()
489
490
491if __name__ == '__main__':
492    main()
493