Turn off debug
[mesa.git] / src / mesa / glapi / glX_proto_size.py
1 #!/usr/bin/env python
2
3 # (C) Copyright IBM Corporation 2004, 2005
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 # IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 # IN THE SOFTWARE.
24 #
25 # Authors:
26 # Ian Romanick <idr@us.ibm.com>
27
28 import gl_XML
29 import glX_XML
30 import license
31 import sys, getopt, copy
32
33
34 class SizeStubFunctionIterator(glX_XML.glXFunctionIterator):
35 """Iterate over functions that need "size" information.
36
37 Iterate over the functions that have variable sized data. First the
38 "set"-type functions are iterated followed by the "get"-type
39 functions.
40 """
41
42 def __init__(self, context):
43 self.data = []
44 self.index = 0
45
46 set_functions = []
47 get_functions = []
48 extra_data = []
49
50 for f in gl_XML.glFunctionIterator(context):
51 if context.glx_enum_functions.has_key(f.name):
52 ef = context.glx_enum_functions[f.name]
53 if ef.is_set():
54 set_functions.append(f)
55 else:
56 get_functions.append(f)
57
58
59 if (context.which_functions & PrintGlxSizeStubs_c.do_set) != 0:
60 self.data += set_functions
61 elif context.get_alias_set:
62 extra_data = set_functions
63
64 if (context.which_functions & PrintGlxSizeStubs_c.do_get) != 0:
65 self.data += get_functions
66
67
68 for f in extra_data + self.data:
69 sig = context.glx_enum_functions[f.name].signature()
70
71 if not context.glx_enum_sigs.has_key(sig):
72 context.glx_enum_sigs[sig] = f.name;
73
74 return
75
76
77 def next(self):
78 if self.index == len(self.data):
79 raise StopIteration
80
81 f = self.data[ self.index ]
82 self.index += 1
83
84 return f
85
86
87 class glXServerEnumFunction(glX_XML.glXEnumFunction):
88 def signature( self ):
89 if self.sig == None:
90 sig = glX_XML.glXEnumFunction.signature(self)
91
92 f = self.context.find_function( self.name )
93 p = f.variable_length_parameter()
94
95 try:
96 sig += "%u" % (p.p_type.size)
97 except Exception,e:
98 print '%s' % (self.name)
99 raise e
100
101 self.sig = sig
102
103 return self.sig;
104
105
106 def Print(self, name):
107 f = self.context.find_function( self.name )
108 self.context.common_func_print_just_header( f )
109
110 fixup = []
111 o = 0
112 for p in f.parameterIterator(1, 1):
113 if f.count_parameter_list.count(p.name) or p.name == f.counter:
114 self.context.common_emit_one_arg(p, o, "pc", " ", 0)
115 fixup.append(p.name)
116
117 o += p.size()
118
119 print ' GLsizei compsize;'
120 print ''
121
122 self.context.common_emit_fixups(fixup)
123
124 print ''
125 print ' compsize = %s;' % (context.size_call(context, f))
126 p = f.variable_length_parameter()
127 print ' return __GLX_PAD(%s);' % (p.size_string())
128
129 print '}'
130 print ''
131
132
133 class PrintGlxSizeStubs_common(glX_XML.GlxProto):
134 do_get = (1 << 0)
135 do_set = (1 << 1)
136 do_get_alias_set = (1 << 2)
137
138 def __init__(self, which_functions):
139 glX_XML.GlxProto.__init__(self)
140 self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004", "IBM")
141 self.aliases = []
142 self.glx_enum_sigs = {}
143 self.name = "glX_proto_size.py (from Mesa)"
144 self.which_functions = which_functions
145
146 if (((which_functions & PrintGlxSizeStubs_common.do_set) != 0) and ((which_functions & PrintGlxSizeStubs_common.do_get) != 0)) or ((which_functions & PrintGlxSizeStubs_common.do_get_alias_set) != 0):
147 self.get_alias_set = 1
148 else:
149 self.get_alias_set = 0
150
151
152 def functionIterator(self):
153 return SizeStubFunctionIterator(self)
154
155
156 class PrintGlxSizeStubs_c(PrintGlxSizeStubs_common):
157 def printRealHeader(self):
158 print ''
159 print '#include <GL/gl.h>'
160 if self.which_functions & self.do_get:
161 print '#include "indirect_size_get.h"'
162
163 print '#include "indirect_size.h"'
164
165 print ''
166 self.printHaveAlias()
167 print ''
168 self.printPure()
169 print ''
170 self.printFastcall()
171 print ''
172 self.printVisibility( "INTERNAL", "internal" )
173 print ''
174 print ''
175 print '#ifdef HAVE_ALIAS'
176 print '# define ALIAS2(from,to) \\'
177 print ' INTERNAL PURE FASTCALL GLint __gl ## from ## _size( GLenum e ) \\'
178 print ' __attribute__ ((alias( # to )));'
179 print '# define ALIAS(from,to) ALIAS2( from, __gl ## to ## _size )'
180 print '#else'
181 print '# define ALIAS(from,to) \\'
182 print ' INTERNAL PURE FASTCALL GLint __gl ## from ## _size( GLenum e ) \\'
183 print ' { return __gl ## to ## _size( e ); }'
184 print '#endif'
185 print ''
186 print ''
187
188
189 def printRealFooter(self):
190 for a in self.aliases:
191 print a
192
193
194 def printFunction(self, f):
195 ef = self.glx_enum_functions[f.name]
196 n = self.glx_enum_sigs[ ef.signature() ];
197
198 if n != f.name:
199 a = 'ALIAS( %s, %s )' % (f.name, n)
200 self.aliases.append(a)
201 else:
202 ef.Print( f.name )
203
204
205
206 class PrintGlxSizeStubs_h(PrintGlxSizeStubs_common):
207 def printRealHeader(self):
208 print """/**
209 * \\file
210 * Prototypes for functions used to determine the number of data elements in
211 * various GLX protocol messages.
212 *
213 * \\author Ian Romanick <idr@us.ibm.com>
214 */
215 """
216 self.printPure();
217 print ''
218 self.printFastcall();
219 print ''
220 self.printVisibility( "INTERNAL", "internal" );
221 print ''
222
223
224 def printFunction(self, f):
225 ef = self.glx_enum_functions[f.name]
226 print 'extern INTERNAL PURE FASTCALL GLint __gl%s_size(GLenum);' % (f.name)
227
228
229 class PrintGlxReqSize_common(glX_XML.GlxProto):
230 """Common base class for PrintGlxSizeReq_h and PrintGlxSizeReq_h.
231
232 The main purpose of this common base class is to provide the infrastructure
233 for the derrived classes to iterate over the same set of functions.
234 """
235
236 def __init__(self):
237 glX_XML.GlxProto.__init__(self)
238 self.name = "glX_proto_size.py (from Mesa)"
239 self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2005", "IBM")
240 self.aliases = []
241 self.glx_enum_sigs = {}
242 self.size_functions = []
243
244
245 def endElementNS(self, name, qname):
246 [uri, true_name] = name
247 if true_name == "function":
248 f = self.current_object
249 if f.glx_rop and not f.ignore and f.fn_alias == None and f.vectorequiv == None:
250
251 if self.glx_enum_functions.has_key(f.name) or f.image or f.server_handcode:
252 self.size_functions.append( f )
253 else:
254 for p in f.parameterIterator(1,2):
255 if p.counter and not p.is_output:
256 self.size_functions.append( f )
257 break
258
259 glX_XML.GlxProto.endElementNS(self, name, qname)
260
261
262 def functionIterator(self):
263 return self.size_functions
264
265
266 class PrintGlxReqSize_h(PrintGlxReqSize_common):
267 def __init__(self):
268 PrintGlxReqSize_common.__init__(self)
269 self.header_tag = "_INDIRECT_REQSIZE_H_"
270
271
272 def printRealHeader(self):
273 self.printVisibility("HIDDEN", "hidden")
274 print ''
275 self.printPure()
276 print ''
277
278
279 def printFunction(self, f):
280 print 'extern PURE HIDDEN int __glX%sReqSize(const GLbyte *pc, Bool swap);' % (f.name)
281
282
283 class PrintGlxReqSize_c(PrintGlxReqSize_common):
284 def __init__(self):
285 PrintGlxReqSize_common.__init__(self)
286 self.counter_sigs = {}
287
288
289 def createEnumFunction(self, n):
290 return glXServerEnumFunction(n, self)
291
292
293 def printRealHeader(self):
294 print ''
295 print '#include <GL/gl.h>'
296 print '#include <byteswap.h>'
297 print '#include "glxserver.h"'
298 print '#include "indirect_size.h"'
299 print '#include "indirect_reqsize.h"'
300
301 print ''
302 print '#define __GLX_PAD(x) (((x) + 3) & ~3)'
303 print ''
304 self.printHaveAlias()
305 print ''
306 print '#ifdef HAVE_ALIAS'
307 print '# define ALIAS2(from,to) \\'
308 print ' GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap ) \\'
309 print ' __attribute__ ((alias( # to )));'
310 print '# define ALIAS(from,to) ALIAS2( from, __glX ## to ## ReqSize )'
311 print '#else'
312 print '# define ALIAS(from,to) \\'
313 print ' GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap ) \\'
314 print ' { return __glX ## to ## ReqSize( pc, swap ); }'
315 print '#endif'
316 print ''
317 print ''
318
319
320 def printRealFooter(self):
321 for a in self.aliases:
322 print a
323
324
325 def printFunction(self, f):
326 # Even though server-handcode fuctions are on "the list",
327 # and prototypes are generated for them, there isn't enough
328 # information to generate a size function. If there was
329 # enough information, they probably wouldn't need to be
330 # handcoded in the first place!
331
332 if f.server_handcode: return
333
334 if self.glx_enum_functions.has_key(f.name):
335 ef = self.glx_enum_functions[f.name]
336
337 sig = ef.signature();
338 if self.glx_enum_sigs.has_key(sig):
339 n = self.glx_enum_sigs[sig];
340 a = 'ALIAS( %s, %s )' % (f.name, n)
341 self.aliases.append(a)
342 else:
343 ef.Print( f.name )
344 self.glx_enum_sigs[sig] = f.name;
345 elif f.image:
346 self.printPixelFunction(f)
347 else:
348 for p in f.parameterIterator(1,2):
349 if p.counter and not p.is_output:
350 self.printCountedFunction(f)
351 break
352
353
354 def common_emit_fixups(self, fixup):
355 """Utility function to emit conditional byte-swaps."""
356
357 if fixup:
358 print ' if (swap) {'
359 for name in fixup:
360 print ' %-14s = bswap_32( %s );' % (name, name)
361 print ' }'
362
363 return
364
365
366 def common_emit_one_arg(self, p, offset, pc, indent, adjust):
367 dst = '%s %s' % (p.p_type_string, p.name)
368 src = '(%s *)' % (p.p_type_string)
369 print '%s%-18s = *%11s(%s + %u);' % (indent, dst, src, pc, offset + adjust);
370 return
371
372
373 def common_func_print_just_header(self, f):
374 print 'int'
375 print '__glX%sReqSize( const GLbyte * pc, Bool swap )' % (f.name)
376 print '{'
377
378
379 def printPixelFunction(self, f):
380 self.common_func_print_just_header(f)
381
382 [dim, w, h, d, junk] = f.dimensions()
383
384 offset = f.offset_of_first_parameter()
385
386 print ' GLint row_length = * (GLint *)(pc + 4);'
387
388 if dim < 3:
389 fixup = ['row_length', 'skip_rows', 'alignment']
390 print ' GLint image_height = 0;'
391 print ' GLint skip_images = 0;'
392 print ' GLint skip_rows = * (GLint *)(pc + 8);'
393 print ' GLint alignment = * (GLint *)(pc + 16);'
394 else:
395 fixup = ['row_length', 'image_height', 'skip_rows', 'skip_images', 'alignment']
396 print ' GLint image_height = * (GLint *)(pc + 8);'
397 print ' GLint skip_rows = * (GLint *)(pc + 16);'
398 print ' GLint skip_images = * (GLint *)(pc + 20);'
399 print ' GLint alignment = * (GLint *)(pc + 32);'
400
401 for p in f.parameterIterator(1, 2):
402 if p.name in [w, h, d, f.image.img_format, f.image.img_type, f.image.img_target]:
403 self.common_emit_one_arg(p, offset, "pc", " ", 0 )
404 fixup.append( p.name )
405
406 offset += p.size()
407
408 print ''
409
410 self.common_emit_fixups(fixup)
411
412 print ''
413 print ' return __glXImageSize(%s, %s, %s, %s, %s, %s,' % (f.image.img_format, f.image.img_type, f.image.img_target, w, h, d )
414 print ' image_height, row_length, skip_images,'
415 print ' skip_rows, alignment);'
416 print '}'
417 print ''
418 return
419
420
421 def printCountedFunction(self, f):
422
423 sig = ""
424 offset = 0
425 fixup = []
426 params = []
427 plus = ''
428 size = ''
429 param_offsets = {}
430
431 # Calculate the offset of each counter parameter and the
432 # size string for the variable length parameter(s). While
433 # that is being done, calculate a unique signature for this
434 # function.
435
436 for p in f.parameterIterator(1,2):
437 if p.is_counter:
438 param_offsets[ p.name ] = offset
439 fixup.append( p.name )
440 params.append( [p, offset] )
441 elif p.counter:
442 s = p.p_type.size
443 if s == 0: s = 1
444
445 sig += "(%u,%u)" % (param_offsets[p.counter], s)
446 size += '%s%s' % (plus, p.size_string())
447 plus = ' + '
448
449
450 offset += p.size()
451
452
453 # If the calculated signature matches a function that has
454 # already be emitted, don't emit this function. Instead, add
455 # it to the list of function aliases.
456
457 if self.counter_sigs.has_key(sig):
458 n = self.counter_sigs[sig];
459 a = 'ALIAS( %s, %s )' % (f.name, n)
460 self.aliases.append(a)
461 else:
462 self.counter_sigs[sig] = f.name
463
464 self.common_func_print_just_header(f)
465
466 for [p, offset] in params:
467 self.common_emit_one_arg(p, offset, "pc", " ", 0 )
468
469
470 print ''
471 self.common_emit_fixups(fixup)
472 print ''
473
474 print ' return __GLX_PAD(%s);' % (size)
475 print '}'
476 print ''
477
478 return
479
480
481 def show_usage():
482 print "Usage: %s [-f input_file_name] -m output_mode [--only-get | --only-set] [--get-alias-set]" % sys.argv[0]
483 print " -m output_mode Output mode can be one of 'size_c' or 'size_h'."
484 print " --only-get Only emit 'get'-type functions."
485 print " --only-set Only emit 'set'-type functions."
486 print " --get-alias-set When only 'get'-type functions are emitted, allow them"
487 print " to be aliases to 'set'-type funcitons."
488 print ""
489 print "By default, both 'get' and 'set'-type functions are emitted."
490 sys.exit(1)
491
492
493 if __name__ == '__main__':
494 file_name = "gl_API.xml"
495
496 try:
497 (args, trail) = getopt.getopt(sys.argv[1:], "f:m:h:", ["only-get", "only-set", "get-alias-set", "header-tag"])
498 except Exception,e:
499 show_usage()
500
501 mode = None
502 header_tag = None
503 which_functions = PrintGlxSizeStubs_common.do_get | PrintGlxSizeStubs_common.do_set
504
505 for (arg,val) in args:
506 if arg == "-f":
507 file_name = val
508 elif arg == "-m":
509 mode = val
510 elif arg == "--only-get":
511 which_functions = PrintGlxSizeStubs_common.do_get
512 elif arg == "--only-set":
513 which_functions = PrintGlxSizeStubs_common.do_set
514 elif arg == "--get-alias-set":
515 which_functions |= PrintGlxSizeStubs_common.do_get_alias_set
516 elif (arg == '-h') or (arg == "--header-tag"):
517 header_tag = val
518
519 if mode == "size_c":
520 dh = PrintGlxSizeStubs_c( which_functions )
521 elif mode == "size_h":
522 dh = PrintGlxSizeStubs_h( which_functions )
523 if header_tag:
524 dh.header_tag = header_tag
525 elif mode == "reqsize_c":
526 dh = PrintGlxReqSize_c()
527 elif mode == "reqsize_h":
528 dh = PrintGlxReqSize_h()
529 else:
530 show_usage()
531
532 gl_XML.parse_GL_API( dh, file_name )