gallium,util: Pull u_indices and u_primconvert back into gallium
[platform/upstream/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 import argparse
28 import itertools
29 import typing as T
30
31 GENERATE, UBYTE, USHORT, UINT = 'generate', 'ubyte', 'ushort', 'uint'
32 FIRST, LAST = 'first', 'last'
33 PRDISABLE, PRENABLE = 'prdisable', 'prenable'
34
35 INTYPES = (GENERATE, UBYTE, USHORT, UINT)
36 OUTTYPES = (USHORT, UINT)
37 PVS=(FIRST, LAST)
38 PRS=(PRDISABLE, PRENABLE)
39 PRIMS=('points',
40        'lines',
41        'linestrip',
42        'lineloop',
43        'tris',
44        'trifan',
45        'tristrip',
46        'quads',
47        'quadstrip',
48        'polygon',
49        'linesadj',
50        'linestripadj',
51        'trisadj',
52        'tristripadj')
53
54 LONGPRIMS=('PIPE_PRIM_POINTS',
55            'PIPE_PRIM_LINES',
56            'PIPE_PRIM_LINE_STRIP',
57            'PIPE_PRIM_LINE_LOOP',
58            'PIPE_PRIM_TRIANGLES',
59            'PIPE_PRIM_TRIANGLE_FAN',
60            'PIPE_PRIM_TRIANGLE_STRIP',
61            'PIPE_PRIM_QUADS',
62            'PIPE_PRIM_QUAD_STRIP',
63            'PIPE_PRIM_POLYGON',
64            'PIPE_PRIM_LINES_ADJACENCY',
65            'PIPE_PRIM_LINE_STRIP_ADJACENCY',
66            'PIPE_PRIM_TRIANGLES_ADJACENCY',
67            'PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY')
68
69 longprim = dict(zip(PRIMS, LONGPRIMS))
70 intype_idx = dict(ubyte='IN_UBYTE', ushort='IN_USHORT', uint='IN_UINT')
71 outtype_idx = dict(ushort='OUT_USHORT', uint='OUT_UINT')
72 pv_idx = dict(first='PV_FIRST', last='PV_LAST')
73 pr_idx = dict(prdisable='PR_DISABLE', prenable='PR_ENABLE')
74
75 def prolog(f: 'T.TextIO') -> None:
76     f.write('/* File automatically generated by u_indices_gen.py */\n')
77     f.write(copyright)
78     f.write(r'''
79
80 /**
81  * @file
82  * Functions to translate and generate index lists
83  */
84
85 #include "indices/u_indices_priv.h"
86 #include "util/u_debug.h"
87 #include "util/u_memory.h"
88
89 #include "c99_compat.h"
90
91 static u_translate_func translate[IN_COUNT][OUT_COUNT][PV_COUNT][PV_COUNT][PR_COUNT][PRIM_COUNT];
92 static u_generate_func  generate[OUT_COUNT][PV_COUNT][PV_COUNT][PRIM_COUNT];
93
94
95 ''')
96
97 def vert( intype, outtype, v0 ):
98     if intype == GENERATE:
99         return '(' + outtype + ')(' + v0 + ')'
100     else:
101         return '(' + outtype + ')in[' + v0 + ']'
102
103 def shape(f: 'T.TextIO', intype, outtype, ptr, *vertices):
104     for i, v in enumerate(vertices):
105         f.write(f'      ({ptr})[{i}] = {vert(intype, outtype, v)};\n')
106
107 def do_point(f: 'T.TextIO', intype, outtype, ptr, v0 ):
108     shape(f, intype, outtype, ptr, v0 )
109
110 def do_line(f: 'T.TextIO', intype, outtype, ptr, v0, v1, inpv, outpv ):
111     if inpv == outpv:
112         shape(f, intype, outtype, ptr, v0, v1 )
113     else:
114         shape(f, intype, outtype, ptr, v1, v0 )
115
116 def do_tri(f: 'T.TextIO', intype, outtype, ptr, v0, v1, v2, inpv, outpv ):
117     if inpv == outpv:
118         shape(f, intype, outtype, ptr, v0, v1, v2 )
119     elif inpv == FIRST:
120         shape(f, intype, outtype, ptr, v1, v2, v0 )
121     else:
122         shape(f, intype, outtype, ptr, v2, v0, v1 )
123
124 def do_quad(f: 'T.TextIO', intype, outtype, ptr, v0, v1, v2, v3, inpv, outpv ):
125     if inpv == LAST:
126         do_tri(f, intype, outtype, ptr+'+0',  v0, v1, v3, inpv, outpv );
127         do_tri(f, intype, outtype, ptr+'+3',  v1, v2, v3, inpv, outpv );
128     else:
129         do_tri(f, intype, outtype, ptr+'+0',  v0, v1, v2, inpv, outpv );
130         do_tri(f, intype, outtype, ptr+'+3',  v0, v2, v3, inpv, outpv );
131
132 def do_lineadj(f: 'T.TextIO', intype, outtype, ptr, v0, v1, v2, v3, inpv, outpv ):
133     if inpv == outpv:
134         shape(f, intype, outtype, ptr, v0, v1, v2, v3 )
135     else:
136         shape(f, intype, outtype, ptr, v3, v2, v1, v0 )
137
138 def do_triadj(f: 'T.TextIO', intype, outtype, ptr, v0, v1, v2, v3, v4, v5, inpv, outpv ):
139     if inpv == outpv:
140         shape(f, intype, outtype, ptr, v0, v1, v2, v3, v4, v5 )
141     else:
142         shape(f, intype, outtype, ptr, v4, v5, v0, v1, v2, v3 )
143
144 def name(intype, outtype, inpv, outpv, pr, prim):
145     if intype == GENERATE:
146         return 'generate_' + prim + '_' + outtype + '_' + inpv + '2' + outpv
147     else:
148         return 'translate_' + prim + '_' + intype + '2' + outtype + '_' + inpv + '2' + outpv + '_' + pr
149
150 def preamble(f: 'T.TextIO', intype, outtype, inpv, outpv, pr, prim):
151     f.write('static void ' + name( intype, outtype, inpv, outpv, pr, prim ) + '(\n')
152     if intype != GENERATE:
153         f.write('    const void * restrict _in,\n')
154     f.write('    unsigned start,\n')
155     if intype != GENERATE:
156         f.write('    unsigned in_nr,\n')
157     f.write('    unsigned out_nr,\n')
158     if intype != GENERATE:
159         f.write('    unsigned restart_index,\n')
160     f.write('    void * restrict _out )\n')
161     f.write('{\n')
162     if intype != GENERATE:
163         f.write('  const ' + intype + '* restrict in = (const ' + intype + '* restrict)_in;\n')
164     f.write('  ' + outtype + ' * restrict out = (' + outtype + '* restrict)_out;\n')
165     f.write('  unsigned i, j;\n')
166     f.write('  (void)j;\n')
167
168 def postamble(f: 'T.TextIO'):
169     f.write('}\n')
170
171 def prim_restart(f: 'T.TextIO', in_verts, out_verts, out_prims, close_func = None):
172     f.write('restart:\n')
173     f.write('      if (i + ' + str(in_verts) + ' > in_nr) {\n')
174     for i, j in itertools.product(range(out_prims), range(out_verts)):
175         f.write('         (out+j+' + str(out_verts * i) + ')[' + str(j) + '] = restart_index;\n')
176     f.write('         continue;\n')
177     f.write('      }\n')
178     for i in range(in_verts):
179         f.write('      if (in[i + ' + str(i) + '] == restart_index) {\n')
180         f.write('         i += ' + str(i + 1) + ';\n')
181
182         if close_func is not None:
183             close_func(i)
184
185         f.write('         goto restart;\n')
186         f.write('      }\n')
187
188 def points(f: 'T.TextIO', intype, outtype, inpv, outpv, pr):
189     preamble(f, intype, outtype, inpv, outpv, pr, prim='points')
190     f.write('  for (i = start, j = 0; j < out_nr; j++, i++) {\n')
191     do_point(f, intype, outtype, 'out+j',  'i' );
192     f.write('   }\n')
193     postamble(f)
194
195 def lines(f: 'T.TextIO', intype, outtype, inpv, outpv, pr):
196     preamble(f, intype, outtype, inpv, outpv, pr, prim='lines')
197     f.write('  for (i = start, j = 0; j < out_nr; j+=2, i+=2) {\n')
198     do_line(f,  intype, outtype, 'out+j',  'i', 'i+1', inpv, outpv );
199     f.write('   }\n')
200     postamble(f)
201
202 def linestrip(f: 'T.TextIO', intype, outtype, inpv, outpv, pr):
203     preamble(f, intype, outtype, inpv, outpv, pr, prim='linestrip')
204     f.write('  for (i = start, j = 0; j < out_nr; j+=2, i++) {\n')
205     do_line(f, intype, outtype, 'out+j',  'i', 'i+1', inpv, outpv );
206     f.write('   }\n')
207     postamble(f)
208
209 def lineloop(f: 'T.TextIO', intype, outtype, inpv, outpv, pr):
210     preamble(f, intype, outtype, inpv, outpv, pr, prim='lineloop')
211     f.write('  unsigned end = start;\n')
212     f.write('  for (i = start, j = 0; j < out_nr - 2; j+=2, i++) {\n')
213     if pr == PRENABLE:
214         def close_func(index):
215             do_line(f, intype, outtype, 'out+j',  'end', 'start', inpv, outpv )
216             f.write('         start = i;\n')
217             f.write('         end = start;\n')
218             f.write('         j += 2;\n')
219
220         prim_restart(f, 2, 2, 1, close_func)
221
222     do_line(f, intype, outtype, 'out+j',  'i', 'i+1', inpv, outpv );
223     f.write('      end = i+1;\n')
224     f.write('   }\n')
225     do_line(f, intype, outtype, 'out+j',  'end', 'start', inpv, outpv );
226     postamble(f)
227
228 def tris(f: 'T.TextIO', intype, outtype, inpv, outpv, pr):
229     preamble(f, intype, outtype, inpv, outpv, pr, prim='tris')
230     f.write('  for (i = start, j = 0; j < out_nr; j+=3, i+=3) {\n')
231     do_tri(f, intype, outtype, 'out+j',  'i', 'i+1', 'i+2', inpv, outpv );
232     f.write('   }\n')
233     postamble(f)
234
235
236 def tristrip(f: 'T.TextIO', intype, outtype, inpv, outpv, pr):
237     preamble(f, intype, outtype, inpv, outpv, pr, prim='tristrip')
238     f.write('  for (i = start, j = 0; j < out_nr; j+=3, i++) {\n')
239     if inpv == FIRST:
240         do_tri(f, intype, outtype, 'out+j',  'i', 'i+1+(i&1)', 'i+2-(i&1)', inpv, outpv );
241     else:
242         do_tri(f, intype, outtype, 'out+j',  'i+(i&1)', 'i+1-(i&1)', 'i+2', inpv, outpv );
243     f.write('   }\n')
244     postamble(f)
245
246
247 def trifan(f: 'T.TextIO', intype, outtype, inpv, outpv, pr):
248     preamble(f, intype, outtype, inpv, outpv, pr, prim='trifan')
249     f.write('  for (i = start, j = 0; j < out_nr; j+=3, i++) {\n')
250
251     if pr == PRENABLE:
252         def close_func(index):
253             f.write('         start = i;\n')
254         prim_restart(f, 3, 3, 1, close_func)
255
256     if inpv == FIRST:
257         do_tri(f, intype, outtype, 'out+j',  'i+1', 'i+2', 'start', inpv, outpv );
258     else:
259         do_tri(f, intype, outtype, 'out+j',  'start', 'i+1', 'i+2', inpv, outpv );
260
261     f.write('   }')
262     postamble(f)
263
264
265
266 def polygon(f: 'T.TextIO', intype, outtype, inpv, outpv, pr):
267     preamble(f, intype, outtype, inpv, outpv, pr, prim='polygon')
268     f.write('  for (i = start, j = 0; j < out_nr; j+=3, i++) {\n')
269     if pr == PRENABLE:
270         def close_func(index):
271             f.write('         start = i;\n')
272         prim_restart(f, 3, 3, 1, close_func)
273
274     if inpv == FIRST:
275         do_tri(f, intype, outtype, 'out+j',  'start', 'i+1', 'i+2', inpv, outpv );
276     else:
277         do_tri(f, intype, outtype, 'out+j',  'i+1', 'i+2', 'start', inpv, outpv );
278     f.write('   }')
279     postamble(f)
280
281
282 def quads(f: 'T.TextIO', intype, outtype, inpv, outpv, pr):
283     preamble(f, intype, outtype, inpv, outpv, pr, prim='quads')
284     f.write('  for (i = start, j = 0; j < out_nr; j+=6, i+=4) {\n')
285     if pr == PRENABLE:
286         prim_restart(f, 4, 3, 2)
287
288     do_quad(f, intype, outtype, 'out+j', 'i+0', 'i+1', 'i+2', 'i+3', inpv, outpv );
289     f.write('   }\n')
290     postamble(f)
291
292
293 def quadstrip(f: 'T.TextIO', intype, outtype, inpv, outpv, pr):
294     preamble(f, intype, outtype, inpv, outpv, pr, prim='quadstrip')
295     f.write('  for (i = start, j = 0; j < out_nr; j+=6, i+=2) {\n')
296     if pr == PRENABLE:
297         prim_restart(f, 4, 3, 2)
298
299     if inpv == LAST:
300         do_quad(f, intype, outtype, 'out+j', 'i+2', 'i+0', 'i+1', 'i+3', inpv, outpv );
301     else:
302         do_quad(f, intype, outtype, 'out+j', 'i+0', 'i+1', 'i+3', 'i+2', inpv, outpv );
303     f.write('   }\n')
304     postamble(f)
305
306
307 def linesadj(f: 'T.TextIO', intype, outtype, inpv, outpv, pr):
308     preamble(f, intype, outtype, inpv, outpv, pr, prim='linesadj')
309     f.write('  for (i = start, j = 0; j < out_nr; j+=4, i+=4) {\n')
310     do_lineadj(f, intype, outtype, 'out+j',  'i+0', 'i+1', 'i+2', 'i+3', inpv, outpv )
311     f.write('  }\n')
312     postamble(f)
313
314
315 def linestripadj(f: 'T.TextIO', intype, outtype, inpv, outpv, pr):
316     preamble(f, intype, outtype, inpv, outpv, pr, prim='linestripadj')
317     f.write('  for (i = start, j = 0; j < out_nr; j+=4, i++) {\n')
318     do_lineadj(f, intype, outtype, 'out+j',  'i+0', 'i+1', 'i+2', 'i+3', inpv, outpv )
319     f.write('  }\n')
320     postamble(f)
321
322
323 def trisadj(f: 'T.TextIO', intype, outtype, inpv, outpv, pr):
324     preamble(f, intype, outtype, inpv, outpv, pr, prim='trisadj')
325     f.write('  for (i = start, j = 0; j < out_nr; j+=6, i+=6) {\n')
326     do_triadj(f, intype, outtype, 'out+j',  'i+0', 'i+1', 'i+2', 'i+3',
327               'i+4', 'i+5', inpv, outpv )
328     f.write('  }\n')
329     postamble(f)
330
331
332 def tristripadj(f: 'T.TextIO', intype, outtype, inpv, outpv, pr):
333     preamble(f, intype, outtype, inpv, outpv, pr, prim='tristripadj')
334     f.write('  for (i = start, j = 0; j < out_nr; i+=2, j+=6) {\n')
335     f.write('    if (i % 4 == 0) {\n')
336     f.write('      /* even triangle */\n')
337     do_triadj(f, intype, outtype, 'out+j',
338               'i+0', 'i+1', 'i+2', 'i+3', 'i+4', 'i+5', inpv, outpv )
339     f.write('    } else {\n')
340     f.write('      /* odd triangle */\n')
341     do_triadj(f, intype, outtype, 'out+j',
342               'i+2', 'i-2', 'i+0', 'i+3', 'i+4', 'i+6', inpv, outpv )
343     f.write('    }\n')
344     f.write('  }\n')
345     postamble(f)
346
347
348 def emit_funcs(f: 'T.TextIO') -> None:
349     for intype, outtype, inpv, outpv, pr in itertools.product(
350             INTYPES, OUTTYPES, [FIRST, LAST], [FIRST, LAST], [PRDISABLE, PRENABLE]):
351         if pr == PRENABLE and intype == GENERATE:
352             continue
353         points(f, intype, outtype, inpv, outpv, pr)
354         lines(f, intype, outtype, inpv, outpv, pr)
355         linestrip(f, intype, outtype, inpv, outpv, pr)
356         lineloop(f, intype, outtype, inpv, outpv, pr)
357         tris(f, intype, outtype, inpv, outpv, pr)
358         tristrip(f, intype, outtype, inpv, outpv, pr)
359         trifan(f, intype, outtype, inpv, outpv, pr)
360         quads(f, intype, outtype, inpv, outpv, pr)
361         quadstrip(f, intype, outtype, inpv, outpv, pr)
362         polygon(f, intype, outtype, inpv, outpv, pr)
363         linesadj(f, intype, outtype, inpv, outpv, pr)
364         linestripadj(f, intype, outtype, inpv, outpv, pr)
365         trisadj(f, intype, outtype, inpv, outpv, pr)
366         tristripadj(f, intype, outtype, inpv, outpv, pr)
367
368 def init(f: 'T.TextIO', intype, outtype, inpv, outpv, pr, prim):
369     if intype == GENERATE:
370         f.write('generate[' +
371                 outtype_idx[outtype] +
372                 '][' + pv_idx[inpv] +
373                 '][' + pv_idx[outpv] +
374                 '][' + longprim[prim] +
375                 '] = ' + name( intype, outtype, inpv, outpv, pr, prim ) + ';\n')
376     else:
377         f.write('translate[' +
378                 intype_idx[intype] +
379                 '][' + outtype_idx[outtype] +
380                 '][' + pv_idx[inpv] +
381                 '][' + pv_idx[outpv] +
382                 '][' + pr_idx[pr] +
383                 '][' + longprim[prim] +
384                 '] = ' + name( intype, outtype, inpv, outpv, pr, prim ) + ';\n')
385
386
387 def emit_all_inits(f: 'T.TextIO'):
388     for intype, outtype, inpv, outpv, pr, prim in itertools.product(
389             INTYPES, OUTTYPES, PVS, PVS, PRS, PRIMS):
390         init(f,intype, outtype, inpv, outpv, pr, prim)
391
392 def emit_init(f: 'T.TextIO'):
393     f.write('void u_index_init( void )\n')
394     f.write('{\n')
395     f.write('  static int firsttime = 1;\n')
396     f.write('  if (!firsttime) return;\n')
397     f.write('  firsttime = 0;\n')
398     emit_all_inits(f)
399     f.write('}\n')
400
401
402
403
404 def epilog(f: 'T.TextIO') -> None:
405     f.write('#include "indices/u_indices.c"\n')
406
407
408 def main():
409     parser = argparse.ArgumentParser()
410     parser.add_argument('output')
411     args = parser.parse_args()
412
413     with open(args.output, 'w') as f:
414         prolog(f)
415         emit_funcs(f)
416         emit_init(f)
417         epilog(f)
418
419
420 if __name__ == '__main__':
421     main()