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