3 # (C) Copyright IBM Corporation 2004, 2005
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:
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
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
26 # Ian Romanick <idr@us.ibm.com>
31 import sys
, getopt
, copy
34 class SizeStubFunctionIterator(glX_XML
.glXFunctionIterator
):
35 """Iterate over functions that need "size" information.
37 Iterate over the functions that have variable sized data. First the
38 "set"-type functions are iterated followed by the "get"-type
42 def __init__(self
, context
):
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
]
54 set_functions
.append(f
)
56 get_functions
.append(f
)
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
64 if (context
.which_functions
& PrintGlxSizeStubs_c
.do_get
) != 0:
65 self
.data
+= get_functions
68 for f
in extra_data
+ self
.data
:
69 sig
= context
.glx_enum_functions
[f
.name
].signature()
71 if not context
.glx_enum_sigs
.has_key(sig
):
72 context
.glx_enum_sigs
[sig
] = f
.name
;
78 if self
.index
== len(self
.data
):
81 f
= self
.data
[ self
.index
]
87 class glXServerEnumFunction(glX_XML
.glXEnumFunction
):
88 def signature( self
):
90 sig
= glX_XML
.glXEnumFunction
.signature(self
)
92 f
= self
.context
.find_function( self
.name
)
93 p
= f
.variable_length_parameter()
96 sig
+= "%u" % (p
.p_type
.size
)
98 print '%s' % (self
.name
)
106 def Print(self
, name
):
107 f
= self
.context
.find_function( self
.name
)
108 self
.context
.common_func_print_just_header( f
)
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)
119 print ' GLsizei compsize;'
122 self
.context
.common_emit_fixups(fixup
)
125 print ' compsize = %s;' % (context
.size_call(context
, f
))
126 p
= f
.variable_length_parameter()
127 print ' return __GLX_PAD(%s);' % (p
.size_string())
133 class PrintGlxSizeStubs_common(glX_XML
.GlxProto
):
136 do_get_alias_set
= (1 << 2)
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")
142 self
.glx_enum_sigs
= {}
143 self
.name
= "glX_proto_size.py (from Mesa)"
144 self
.which_functions
= which_functions
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
149 self
.get_alias_set
= 0
152 def functionIterator(self
):
153 return SizeStubFunctionIterator(self
)
156 class PrintGlxSizeStubs_c(PrintGlxSizeStubs_common
):
157 def printRealHeader(self
):
159 print '#include <GL/gl.h>'
160 if self
.which_functions
& self
.do_get
:
161 print '#include "indirect_size_get.h"'
163 print '#include "indirect_size.h"'
166 self
.printHaveAlias()
172 self
.printVisibility( "INTERNAL", "internal" )
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 )'
181 print '# define ALIAS(from,to) \\'
182 print ' INTERNAL PURE FASTCALL GLint __gl ## from ## _size( GLenum e ) \\'
183 print ' { return __gl ## to ## _size( e ); }'
189 def printRealFooter(self
):
190 for a
in self
.aliases
:
194 def printFunction(self
, f
):
195 ef
= self
.glx_enum_functions
[f
.name
]
196 n
= self
.glx_enum_sigs
[ ef
.signature() ];
199 a
= 'ALIAS( %s, %s )' % (f
.name
, n
)
200 self
.aliases
.append(a
)
206 class PrintGlxSizeStubs_h(PrintGlxSizeStubs_common
):
207 def printRealHeader(self
):
210 * Prototypes for functions used to determine the number of data elements in
211 * various GLX protocol messages.
213 * \\author Ian Romanick <idr@us.ibm.com>
218 self
.printFastcall();
220 self
.printVisibility( "INTERNAL", "internal" );
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
)
229 class PrintGlxReqSize_common(glX_XML
.GlxProto
):
230 """Common base class for PrintGlxSizeReq_h and PrintGlxSizeReq_h.
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.
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")
241 self
.glx_enum_sigs
= {}
242 self
.size_functions
= []
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:
251 if self
.glx_enum_functions
.has_key(f
.name
) or f
.image
or f
.server_handcode
:
252 self
.size_functions
.append( f
)
254 for p
in f
.parameterIterator(1,2):
255 if p
.counter
and not p
.is_output
:
256 self
.size_functions
.append( f
)
259 glX_XML
.GlxProto
.endElementNS(self
, name
, qname
)
262 def functionIterator(self
):
263 return self
.size_functions
266 class PrintGlxReqSize_h(PrintGlxReqSize_common
):
268 PrintGlxReqSize_common
.__init
__(self
)
269 self
.header_tag
= "_INDIRECT_REQSIZE_H_"
272 def printRealHeader(self
):
273 self
.printVisibility("HIDDEN", "hidden")
279 def printFunction(self
, f
):
280 print 'extern PURE HIDDEN int __glX%sReqSize(const GLbyte *pc, Bool swap);' % (f
.name
)
283 class PrintGlxReqSize_c(PrintGlxReqSize_common
):
285 PrintGlxReqSize_common
.__init
__(self
)
286 self
.counter_sigs
= {}
289 def createEnumFunction(self
, n
):
290 return glXServerEnumFunction(n
, self
)
293 def printRealHeader(self
):
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"'
302 print '#define __GLX_PAD(x) (((x) + 3) & ~3)'
304 self
.printHaveAlias()
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 )'
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 ); }'
320 def printRealFooter(self
):
321 for a
in self
.aliases
:
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!
332 if f
.server_handcode
: return
334 if self
.glx_enum_functions
.has_key(f
.name
):
335 ef
= self
.glx_enum_functions
[f
.name
]
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
)
344 self
.glx_enum_sigs
[sig
] = f
.name
;
346 self
.printPixelFunction(f
)
348 for p
in f
.parameterIterator(1,2):
349 if p
.counter
and not p
.is_output
:
350 self
.printCountedFunction(f
)
354 def common_emit_fixups(self
, fixup
):
355 """Utility function to emit conditional byte-swaps."""
360 print ' %-14s = bswap_32( %s );' % (name
, name
)
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
);
373 def common_func_print_just_header(self
, f
):
375 print '__glX%sReqSize( const GLbyte * pc, Bool swap )' % (f
.name
)
379 def printPixelFunction(self
, f
):
380 self
.common_func_print_just_header(f
)
382 [dim
, w
, h
, d
, junk
] = f
.dimensions()
384 offset
= f
.offset_of_first_parameter()
386 print ' GLint row_length = * (GLint *)(pc + 4);'
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);'
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);'
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
)
410 self
.common_emit_fixups(fixup
)
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);'
421 def printCountedFunction(self
, f
):
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
436 for p
in f
.parameterIterator(1,2):
438 param_offsets
[ p
.name
] = offset
439 fixup
.append( p
.name
)
440 params
.append( [p
, offset
] )
445 sig
+= "(%u,%u)" % (param_offsets
[p
.counter
], s
)
446 size
+= '%s%s' % (plus
, p
.size_string())
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.
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
)
462 self
.counter_sigs
[sig
] = f
.name
464 self
.common_func_print_just_header(f
)
466 for [p
, offset
] in params
:
467 self
.common_emit_one_arg(p
, offset
, "pc", " ", 0 )
471 self
.common_emit_fixups(fixup
)
474 print ' return __GLX_PAD(%s);' % (size
)
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."
489 print "By default, both 'get' and 'set'-type functions are emitted."
493 if __name__
== '__main__':
494 file_name
= "gl_API.xml"
497 (args
, trail
) = getopt
.getopt(sys
.argv
[1:], "f:m:h:", ["only-get", "only-set", "get-alias-set", "header-tag"])
503 which_functions
= PrintGlxSizeStubs_common
.do_get | PrintGlxSizeStubs_common
.do_set
505 for (arg
,val
) in args
:
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"):
520 dh
= PrintGlxSizeStubs_c( which_functions
)
521 elif mode
== "size_h":
522 dh
= PrintGlxSizeStubs_h( which_functions
)
524 dh
.header_tag
= header_tag
525 elif mode
== "reqsize_c":
526 dh
= PrintGlxReqSize_c()
527 elif mode
== "reqsize_h":
528 dh
= PrintGlxReqSize_h()
532 gl_XML
.parse_GL_API( dh
, file_name
)