376348d5f8e3efb8799e84c2d5fa90361b3207ac
[mesa.git] / src / gallium / auxiliary / indices / u_indices_gen.py
1 copyright = '''
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
27 GENERATE, UBYTE, USHORT, UINT = 'generate', 'ubyte', 'ushort', 'uint'
28 FIRST, LAST = 'first', 'last'
29 PRDISABLE, PRENABLE = 'prdisable', 'prenable'
30
31 INTYPES = (GENERATE, UBYTE, USHORT, UINT)
32 OUTTYPES = (USHORT, UINT)
33 PVS=(FIRST, LAST)
34 PRS=(PRDISABLE, PRENABLE)
35 PRIMS=('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
50 LONGPRIMS=('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
65 longprim = dict(zip(PRIMS, LONGPRIMS))
66 intype_idx = dict(ubyte='IN_UBYTE', ushort='IN_USHORT', uint='IN_UINT')
67 outtype_idx = dict(ushort='OUT_USHORT', uint='OUT_UINT')
68 pv_idx = dict(first='PV_FIRST', last='PV_LAST')
69 pr_idx = dict(prdisable='PR_DISABLE', prenable='PR_ENABLE')
70
71 def 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
86 static 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
95 static 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
106 static u_translate_func translate[IN_COUNT][OUT_COUNT][PV_COUNT][PV_COUNT][PR_COUNT][PRIM_COUNT];
107 static u_generate_func generate[OUT_COUNT][PV_COUNT][PV_COUNT][PRIM_COUNT];
108
109
110 '''
111
112 def vert( intype, outtype, v0 ):
113 if intype == GENERATE:
114 return '(' + outtype + ')(' + v0 + ')'
115 else:
116 return '(' + outtype + ')in[' + v0 + ']'
117
118 def point( intype, outtype, ptr, v0 ):
119 print ' (' + ptr + ')[0] = ' + vert( intype, outtype, v0 ) + ';'
120
121 def line( intype, outtype, ptr, v0, v1 ):
122 print ' (' + ptr + ')[0] = ' + vert( intype, outtype, v0 ) + ';'
123 print ' (' + ptr + ')[1] = ' + vert( intype, outtype, v1 ) + ';'
124
125 def 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
130 def 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
136 def 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
144 def do_point( intype, outtype, ptr, v0 ):
145 point( intype, outtype, ptr, v0 )
146
147 def 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
153 def 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
162 def 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
170 def 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
176 def 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
182 def 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
188 def 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
206 def postamble():
207 print '}'
208
209
210 def 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
217 def 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
224 def 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
231 def 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
239 def 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
247 def 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
258 def 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
267 def 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
302 def 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
338 def 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
376 def 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
384 def 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
392 def 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
401 def 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
417 def 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
440 def 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
459 def 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
468 def 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
480 def epilog():
481 print '#include "indices/u_indices.c"'
482
483
484 def main():
485 prolog()
486 emit_funcs()
487 emit_init()
488 epilog()
489
490
491 if __name__ == '__main__':
492 main()