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