glX_proto_send.py revision 47719fda0c2fba13c81e84e33523d5489263182e
1#!/usr/bin/python2 2 3# (C) Copyright IBM Corporation 2004 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 28from xml.sax import saxutils 29from xml.sax import make_parser 30from xml.sax.handler import feature_namespaces 31 32import gl_XML 33import license 34import sys, getopt 35 36 37def printPure(): 38 print """# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) 39# define PURE __attribute__((pure)) 40# else 41# define PURE 42# endif""" 43 44def printFastcall(): 45 print """# if defined(__i386__) && defined(__GNUC__) 46# define FASTCALL __attribute__((fastcall)) 47# else 48# define FASTCALL 49# endif""" 50 51def printVisibility(S, s): 52 print """# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) 53# define %s __attribute__((visibility("%s"))) 54# else 55# define %s 56# endif""" % (S, s, S) 57 58def printNoinline(): 59 print """# if defined(__GNUC__) 60# define NOINLINE __attribute__((noinline)) 61# else 62# define NOINLINE 63# endif""" 64 65 66class glXItemFactory(gl_XML.glItemFactory): 67 """Factory to create GLX protocol oriented objects derived from glItem.""" 68 69 def create(self, context, name, attrs): 70 if name == "function": 71 return glXFunction(context, name, attrs) 72 elif name == "enum": 73 return glXEnum(context, name, attrs) 74 elif name == "param": 75 return glXParameter(context, name, attrs) 76 else: 77 return gl_XML.glItemFactory.create(self, context, name, attrs) 78 79class glXEnumFunction: 80 def __init__(self, name): 81 self.name = name 82 83 # "enums" is a set of lists. The element in the set is the 84 # value of the enum. The list is the list of names for that 85 # value. For example, [0x8126] = {"POINT_SIZE_MIN", 86 # "POINT_SIZE_MIN_ARB", "POINT_SIZE_MIN_EXT", 87 # "POINT_SIZE_MIN_SGIS"}. 88 89 self.enums = {} 90 91 # "count" is indexed by count values. Each element of count 92 # is a list of index to "enums" that have that number of 93 # associated data elements. For example, [4] = 94 # {GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_EMISSION, 95 # GL_AMBIENT_AND_DIFFUSE} (the enum names are used here, 96 # but the actual hexadecimal values would be in the array). 97 98 self.count = {} 99 100 101 def append(self, count, value, name): 102 if self.enums.has_key( value ): 103 self.enums[value].append(name) 104 else: 105 if not self.count.has_key(count): 106 self.count[count] = [] 107 108 self.enums[value] = [] 109 self.enums[value].append(name) 110 self.count[count].append(value) 111 112 113 def signature( self ): 114 sig = "" 115 for i in self.count: 116 for e in self.count[i]: 117 sig += "%04x,%u," % (e, i) 118 119 return sig; 120 121 122 def PrintUsingTable(self): 123 """Emit the body of the __gl*_size function using a pair 124 of look-up tables and a mask. The mask is calculated such 125 that (e & mask) is unique for all the valid values of e for 126 this function. The result of (e & mask) is used as an index 127 into the first look-up table. If it matches e, then the 128 same entry of the second table is returned. Otherwise zero 129 is returned. 130 131 It seems like this should cause better code to be generated. 132 However, on x86 at least, the resulting .o file is about 20% 133 larger then the switch-statment version. I am leaving this 134 code in because the results may be different on other 135 platforms (e.g., PowerPC or x86-64).""" 136 137 return 0 138 count = 0 139 for a in self.enums: 140 count += 1 141 142 # Determine if there is some mask M, such that M = (2^N) - 1, 143 # that will generate unique values for all of the enums. 144 145 mask = 0 146 for i in [1, 2, 3, 4, 5, 6, 7, 8]: 147 mask = (1 << i) - 1 148 149 fail = 0; 150 for a in self.enums: 151 for b in self.enums: 152 if a != b: 153 if (a & mask) == (b & mask): 154 fail = 1; 155 156 if not fail: 157 break; 158 else: 159 mask = 0 160 161 if (mask != 0) and (mask < (2 * count)): 162 masked_enums = {} 163 masked_count = {} 164 165 for i in range(0, mask + 1): 166 masked_enums[i] = "0"; 167 masked_count[i] = 0; 168 169 for c in self.count: 170 for e in self.count[c]: 171 i = e & mask 172 masked_enums[i] = '0x%04x /* %s */' % (e, self.enums[e][0]) 173 masked_count[i] = c 174 175 176 print ' static const GLushort a[%u] = {' % (mask + 1) 177 for e in masked_enums: 178 print ' %s, ' % (masked_enums[e]) 179 print ' };' 180 181 print ' static const GLubyte b[%u] = {' % (mask + 1) 182 for c in masked_count: 183 print ' %u, ' % (masked_count[c]) 184 print ' };' 185 186 print ' const unsigned idx = (e & 0x%02xU);' % (mask) 187 print '' 188 print ' return (e == a[idx]) ? (GLint) b[idx] : 0;' 189 return 1; 190 else: 191 return 0; 192 193 def PrintUsingSwitch(self): 194 """Emit the body of the __gl*_size function using a 195 switch-statement.""" 196 197 print ' switch( e ) {' 198 199 for c in self.count: 200 for e in self.count[c]: 201 first = 1 202 203 # There may be multiple enums with the same 204 # value. This happens has extensions are 205 # promoted from vendor-specific or EXT to 206 # ARB and to the core. Emit the first one as 207 # a case label, and emit the others as 208 # commented-out case labels. 209 210 for j in self.enums[e]: 211 if first: 212 print ' case %s:' % (j) 213 first = 0 214 else: 215 print '/* case %s:*/' % (j) 216 217 print ' return %u;' % (c) 218 219 print ' default: return 0;' 220 print ' }' 221 222 223 def Print(self, name): 224 print 'INTERNAL PURE FASTCALL GLint' 225 print '__gl%s_size( GLenum e )' % (name) 226 print '{' 227 228 if not self.PrintUsingTable(): 229 self.PrintUsingSwitch() 230 231 print '}' 232 print '' 233 234 235 236class glXEnum(gl_XML.glEnum): 237 def __init__(self, context, name, attrs): 238 gl_XML.glEnum.__init__(self, context, name, attrs) 239 self.glx_functions = [] 240 241 def startElement(self, name, attrs): 242 if name == "size": 243 n = attrs.get('name', None) 244 if not self.context.glx_enum_functions.has_key( n ): 245 f = glXEnumFunction( n ) 246 self.context.glx_enum_functions[ f.name ] = f 247 248 temp = attrs.get('count', None) 249 try: 250 c = int(temp) 251 except Exception,e: 252 raise RuntimeError('Invalid count value "%s" for enum "%s" in function "%s" when an integer was expected.' % (temp, self.name, n)) 253 254 self.context.glx_enum_functions[ n ].append( c, self.value, self.name ) 255 else: 256 gl_XML.glEnum.startElement(self, context, name, attrs) 257 return 258 259 260class glXParameter(gl_XML.glParameter): 261 def __init__(self, context, name, attrs): 262 self.order = 1; 263 gl_XML.glParameter.__init__(self, context, name, attrs); 264 265 266class glXFunction(gl_XML.glFunction): 267 glx_rop = 0 268 glx_sop = 0 269 glx_vendorpriv = 0 270 271 # If this is set to true, it means that GLdouble parameters should be 272 # written to the GLX protocol packet in the order they appear in the 273 # prototype. This is different from the "classic" ordering. In the 274 # classic ordering GLdoubles are written to the protocol packet first, 275 # followed by non-doubles. NV_vertex_program was the first extension 276 # to break with this tradition. 277 278 glx_doubles_in_order = 0 279 280 vectorequiv = None 281 handcode = 0 282 ignore = 0 283 can_be_large = 0 284 285 def __init__(self, context, name, attrs): 286 self.vectorequiv = attrs.get('vectorequiv', None) 287 self.count_parameters = None 288 self.counter = None 289 self.output = None 290 self.can_be_large = 0 291 self.reply_always_array = 0 292 293 gl_XML.glFunction.__init__(self, context, name, attrs) 294 return 295 296 def startElement(self, name, attrs): 297 """Process elements within a function that are specific to GLX.""" 298 299 if name == "glx": 300 self.glx_rop = int(attrs.get('rop', "0")) 301 self.glx_sop = int(attrs.get('sop', "0")) 302 self.glx_vendorpriv = int(attrs.get('vendorpriv', "0")) 303 304 if attrs.get('handcode', "false") == "true": 305 self.handcode = 1 306 else: 307 self.handcode = 0 308 309 if attrs.get('ignore', "false") == "true": 310 self.ignore = 1 311 else: 312 self.ignore = 0 313 314 if attrs.get('large', "false") == "true": 315 self.can_be_large = 1 316 else: 317 self.can_be_large = 0 318 319 if attrs.get('doubles_in_order', "false") == "true": 320 self.glx_doubles_in_order = 1 321 else: 322 self.glx_doubles_in_order = 0 323 324 if attrs.get('always_array', "false") == "true": 325 self.reply_always_array = 1 326 else: 327 self.reply_always_array = 0 328 329 else: 330 gl_XML.glFunction.startElement(self, name, attrs) 331 332 333 def append(self, tag_name, p): 334 gl_XML.glFunction.append(self, tag_name, p) 335 336 if p.is_variable_length_array(): 337 p.order = 2; 338 elif not self.glx_doubles_in_order and p.p_type.size == 8: 339 p.order = 0; 340 341 if p.p_count_parameters != None: 342 self.count_parameters = p.p_count_parameters 343 344 if p.is_counter: 345 self.counter = p.name 346 347 if p.is_output: 348 self.output = p 349 350 return 351 352 def variable_length_parameter(self): 353 for param in self.fn_parameters: 354 if param.is_variable_length_array(): 355 return param 356 357 return None 358 359 360 def command_payload_length(self): 361 size = 0 362 size_string = "" 363 for p in self: 364 if p.is_output: continue 365 temp = p.size_string() 366 try: 367 s = int(temp) 368 size += s 369 except Exception,e: 370 size_string = size_string + " + __GLX_PAD(%s)" % (temp) 371 372 return [size, size_string] 373 374 def command_length(self): 375 [size, size_string] = self.command_payload_length() 376 377 if self.glx_rop != 0: 378 size += 4 379 380 size = ((size + 3) & ~3) 381 return "%u%s" % (size, size_string) 382 383 384 def opcode_real_value(self): 385 if self.glx_vendorpriv != 0: 386 if self.needs_reply(): 387 return 17 388 else: 389 return 16 390 else: 391 return self.opcode_value() 392 393 def opcode_value(self): 394 if self.glx_rop != 0: 395 return self.glx_rop 396 elif self.glx_sop != 0: 397 return self.glx_sop 398 elif self.glx_vendorpriv != 0: 399 return self.glx_vendorpriv 400 else: 401 return -1 402 403 def opcode_rop_basename(self): 404 if self.vectorequiv == None: 405 return self.name 406 else: 407 return self.vectorequiv 408 409 def opcode_name(self): 410 if self.glx_rop != 0: 411 return "X_GLrop_%s" % (self.opcode_rop_basename()) 412 elif self.glx_sop != 0: 413 return "X_GLsop_%s" % (self.name) 414 elif self.glx_vendorpriv != 0: 415 return "X_GLvop_%s" % (self.name) 416 else: 417 return "ERROR" 418 419 def opcode_real_name(self): 420 if self.glx_vendorpriv != 0: 421 if self.needs_reply(): 422 return "X_GLXVendorPrivateWithReply" 423 else: 424 return "X_GLXVendorPrivate" 425 else: 426 return self.opcode_name() 427 428 429 def return_string(self): 430 if self.fn_return_type != 'void': 431 return "return retval;" 432 else: 433 return "return;" 434 435 436 def needs_reply(self): 437 return self.fn_return_type != 'void' or self.output != None 438 439 440class GlxProto(gl_XML.FilterGLAPISpecBase): 441 name = "glX_proto_send.py (from Mesa)" 442 443 def __init__(self): 444 gl_XML.FilterGLAPISpecBase.__init__(self) 445 self.factory = glXItemFactory() 446 self.glx_enum_functions = {} 447 448 449 def endElement(self, name): 450 if name == 'OpenGLAPI': 451 # Once all the parsing is done, we have to go back and 452 # fix-up some cross references between different 453 # functions. 454 455 for k in self.functions: 456 f = self.functions[k] 457 if f.vectorequiv != None: 458 equiv = self.find_function(f.vectorequiv) 459 if equiv != None: 460 f.glx_doubles_in_order = equiv.glx_doubles_in_order 461 f.glx_rop = equiv.glx_rop 462 else: 463 raise RuntimeError("Could not find the vector equiv. function %s for %s!" % (f.name, f.vectorequiv)) 464 else: 465 gl_XML.FilterGLAPISpecBase.endElement(self, name) 466 return 467 468 469class PrintGlxProtoStubs(GlxProto): 470 def __init__(self): 471 GlxProto.__init__(self) 472 self.last_category = "" 473 self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004", "IBM") 474 self.generic_sizes = [3, 4, 6, 8, 12, 16, 24, 32] 475 return 476 477 def printRealHeader(self): 478 print '' 479 print '#include <GL/gl.h>' 480 print '#include "indirect.h"' 481 print '#include "glxclient.h"' 482 print '#include "size.h"' 483 print '#include <GL/glxproto.h>' 484 print '' 485 print '#define __GLX_PAD(n) (((n) + 3) & ~3)' 486 print '' 487 printFastcall() 488 printNoinline() 489 print '' 490 print '/* If the size and opcode values are known at compile-time, this will, on' 491 print ' * x86 at least, emit them with a single instruction.' 492 print ' */' 493 print '#define emit_header(dest, op, size) \\' 494 print ' do { union { short s[2]; int i; } temp; \\' 495 print ' temp.s[0] = (size); temp.s[1] = (op); \\' 496 print ' *((int *)(dest)) = temp.i; } while(0)' 497 print '' 498 print """static NOINLINE CARD32 499read_reply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array ) 500{ 501 xGLXSingleReply reply; 502 503 (void) _XReply(dpy, (xReply *) & reply, 0, False); 504 if (size != 0) { 505 if ((reply.size >= 1) || reply_is_always_array) { 506 const GLint bytes = (reply_is_always_array) 507 ? (4 * reply.length) : (reply.size * size); 508 const GLint extra = 4 - (bytes & 3); 509 510 _XRead(dpy, dest, bytes); 511 if ( extra != 0 ) { 512 _XEatData(dpy, extra); 513 } 514 } 515 else { 516 (void) memcpy( dest, &(reply.pad3), size); 517 } 518 } 519 520 return reply.retval; 521} 522 523#define X_GLXSingle 0 524 525static NOINLINE GLubyte * 526setup_single_request( __GLXcontext * gc, GLint sop, GLint cmdlen ) 527{ 528 xGLXSingleReq * req; 529 Display * const dpy = gc->currentDpy; 530 531 (void) __glXFlushRenderBuffer(gc, gc->pc); 532 LockDisplay(dpy); 533 GetReqExtra(GLXSingle, cmdlen, req); 534 req->reqType = gc->majorOpcode; 535 req->contextTag = gc->currentContextTag; 536 req->glxCode = sop; 537 return (GLubyte *)(req) + sz_xGLXSingleReq; 538} 539 540static NOINLINE GLubyte * 541setup_vendor_request( __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen ) 542{ 543 xGLXVendorPrivateReq * req; 544 Display * const dpy = gc->currentDpy; 545 546 (void) __glXFlushRenderBuffer(gc, gc->pc); 547 LockDisplay(dpy); 548 GetReqExtra(GLXVendorPrivate, cmdlen, req); 549 req->reqType = gc->majorOpcode; 550 req->glxCode = code; 551 req->vendorCode = vop; 552 req->contextTag = gc->currentContextTag; 553 return (GLubyte *)(req) + sz_xGLXVendorPrivateReq; 554} 555""" 556 557 for size in self.generic_sizes: 558 self.print_generic_function(size) 559 return 560 561 def printFunction(self, f): 562 if f.fn_offset < 0 or f.handcode or f.ignore: return 563 564 if f.glx_rop != 0 or f.vectorequiv != None: 565 self.printRenderFunction(f) 566 elif f.glx_sop != 0 or f.glx_vendorpriv != 0: 567 self.printSingleFunction(f) 568 else: 569 print "/* Missing GLX protocol for %s. */" % (f.name) 570 571 def print_generic_function(self, n): 572 print """static FASTCALL NOINLINE void 573generic_%u_byte( GLint rop, const void * ptr ) 574{ 575 __GLXcontext * const gc = __glXGetCurrentContext(); 576 const GLuint cmdlen = %u; 577 578 emit_header(gc->pc, rop, cmdlen); 579 (void) memcpy((void *)(gc->pc + 4), ptr, %u); 580 gc->pc += cmdlen; 581 if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); } 582} 583""" % (n, n + 4, n) 584 585 586 def common_emit_one_arg(self, p, offset, pc, indent, adjust): 587 if p.is_output: return 588 589 t = p.p_type 590 if p.is_array(): 591 src_ptr = p.name 592 else: 593 src_ptr = "&" + p.name 594 595 print '%s (void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \ 596 % (indent, pc, offset + adjust, src_ptr, p.size_string() ) 597 598 def common_emit_args(self, f, pc, indent, adjust, skip_vla): 599 # First emit all of the fixed-length 8-byte (i.e., GLdouble) 600 # parameters. 601 602 offset = 0 603 604 if skip_vla: 605 r = [0, 1] 606 else: 607 r = [0, 1, 2] 608 609 for order in r: 610 for p in f: 611 if p.is_output or p.order != order: continue 612 613 self.common_emit_one_arg(p, offset, pc, indent, adjust) 614 offset += p.size() 615 616 617 return offset 618 619 620 def common_func_print_just_header(self, f): 621 print '#define %s %d' % (f.opcode_name(), f.opcode_value()) 622 623 print '%s' % (f.fn_return_type) 624 print '__indirect_gl%s(%s)' % (f.name, f.get_parameter_string()) 625 print '{' 626 627 628 def common_func_print_header(self, f): 629 self.common_func_print_just_header(f) 630 631 print ' __GLXcontext * const gc = __glXGetCurrentContext();' 632 print ' Display * const dpy = gc->currentDpy;' 633 634 if f.fn_return_type != 'void': 635 print ' %s retval = (%s) 0;' % (f.fn_return_type, f.fn_return_type) 636 637 if f.count_parameters != None: 638 print ' const GLuint compsize = __gl%s_size(%s);' % (f.name, f.count_parameters) 639 640 print ' const GLuint cmdlen = %s;' % (f.command_length()) 641 642 if f.counter != None: 643 print ' if (%s < 0) %s' % (f.counter, f.return_string()) 644 645 if f.can_be_large: 646 print ' if (dpy == NULL) return;' 647 print ' if ( ((gc->pc + cmdlen) > gc->bufEnd)' 648 print ' || (cmdlen > gc->maxSmallRenderCommandSize)) {' 649 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);' 650 print ' }' 651 else: 652 print ' (void) dpy;' 653 654 return 655 656 657 def printSingleFunction(self, f): 658 self.common_func_print_header(f) 659 660 print ' if (dpy != NULL) {' 661 662 if f.fn_parameters != []: 663 pc_decl = "GLubyte const * pc =" 664 else: 665 pc_decl = "(void)" 666 667 if f.glx_vendorpriv != 0: 668 print ' %s setup_vendor_request(gc, %s, %s, cmdlen);' % (pc_decl, f.opcode_real_name(), f.opcode_name()) 669 else: 670 print ' %s setup_single_request(gc, %s, cmdlen);' % (pc_decl, f.opcode_name()) 671 672 self.common_emit_args(f, "pc", " ", 0, 0) 673 674 if f.needs_reply(): 675 if f.output != None: 676 output_size = f.output.p_type.size 677 output_str = f.output.name 678 else: 679 output_size = 0 680 output_str = "NULL" 681 682 if f.fn_return_type != 'void': 683 return_str = " retval = (%s)" % (f.fn_return_type) 684 else: 685 return_str = " (void)" 686 687 if f.reply_always_array: 688 aa = "GL_TRUE" 689 else: 690 aa = "GL_FALSE" 691 692 print " %s read_reply(gc->currentDpy, %s, %s, %s);" % (return_str, output_size, output_str, aa) 693 694 print ' UnlockDisplay(gc->currentDpy); SyncHandle();' 695 print ' }' 696 print ' %s' % f.return_string() 697 print '}' 698 print '' 699 return 700 701 702 def printRenderFunction(self, f): 703 # There is a class of GL functions that take a single pointer 704 # as a parameter. This pointer points to a fixed-size chunk 705 # of data, and the protocol for this functions is very 706 # regular. Since they are so regular and there are so many 707 # of them, special case them with generic functions. On 708 # x86, this save about 26KB in the libGL.so binary. 709 710 if f.variable_length_parameter() == None and len(f.fn_parameters) == 1: 711 p = f.fn_parameters[0] 712 if p.is_pointer: 713 [cmdlen, size_string] = f.command_payload_length() 714 if cmdlen in self.generic_sizes: 715 self.common_func_print_just_header(f) 716 print ' generic_%u_byte( %s, %s );' % (cmdlen, f.opcode_real_name(), p.name) 717 print '}' 718 print '' 719 return 720 721 self.common_func_print_header(f) 722 723 if f.can_be_large: 724 print ' if (cmdlen <= gc->maxSmallRenderCommandSize) {' 725 indent = " " 726 else: 727 indent = "" 728 729 print '%s emit_header(gc->pc, %s, cmdlen);' % (indent, f.opcode_real_name()) 730 731 self.common_emit_args(f, "gc->pc", indent, 4, 0) 732 print '%s gc->pc += cmdlen;' % (indent) 733 print '%s if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent) 734 735 if f.can_be_large: 736 print ' }' 737 print ' else {' 738 print ' const GLint op = %s;' % (f.opcode_real_name()) 739 print ' const GLuint cmdlenLarge = cmdlen + 4;' 740 print ' (void) memcpy((void *)(gc->pc + 0), (void *)(&op), 4);' 741 print ' (void) memcpy((void *)(gc->pc + 4), (void *)(&cmdlenLarge), 4);' 742 offset = self.common_emit_args(f, "gc->pc", indent, 8, 1) 743 744 p = f.variable_length_parameter() 745 print ' __glXSendLargeCommand(gc, gc->pc, %u, %s, %s);' % (offset + 8, p.name, p.size_string()) 746 print ' }' 747 748 print '}' 749 print '' 750 return 751 752 753class PrintGlxProtoInit_c(GlxProto): 754 def __init__(self): 755 GlxProto.__init__(self) 756 self.last_category = "" 757 self.license = license.bsd_license_template % ( \ 758"""Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 759(C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM") 760 761 762 def printRealHeader(self): 763 print """/** 764 * \\file indirect_init.c 765 * Initialize indirect rendering dispatch table. 766 * 767 * \\author Kevin E. Martin <kevin@precisioninsight.com> 768 * \\author Brian Paul <brian@precisioninsight.com> 769 * \\author Ian Romanick <idr@us.ibm.com> 770 */ 771 772#include "indirect_init.h" 773#include "indirect.h" 774#include "glapi.h" 775 776 777/** 778 * No-op function used to initialize functions that have no GLX protocol 779 * support. 780 */ 781static int NoOp(void) 782{ 783 return 0; 784} 785 786/** 787 * Create and initialize a new GL dispatch table. The table is initialized 788 * with GLX indirect rendering protocol functions. 789 */ 790__GLapi * __glXNewIndirectAPI( void ) 791{ 792 __GLapi *glAPI; 793 GLuint entries; 794 795 entries = _glapi_get_dispatch_table_size(); 796 glAPI = (__GLapi *) Xmalloc(entries * sizeof(void *)); 797 798 /* first, set all entries to point to no-op functions */ 799 { 800 int i; 801 void **dispatch = (void **) glAPI; 802 for (i = 0; i < entries; i++) { 803 dispatch[i] = (void *) NoOp; 804 } 805 } 806 807 /* now, initialize the entries we understand */""" 808 809 def printRealFooter(self): 810 print """ 811 return glAPI; 812} 813""" 814 815 def printFunction(self, f): 816 if f.fn_offset < 0 or f.ignore: return 817 818 if f.category != self.last_category: 819 self.last_category = f.category 820 print '' 821 print ' /* %s */' % (self.last_category) 822 print '' 823 824 print ' glAPI->%s = __indirect_gl%s;' % (f.name, f.name) 825 826 827class PrintGlxProtoInit_h(GlxProto): 828 def __init__(self): 829 GlxProto.__init__(self) 830 self.last_category = "" 831 self.license = license.bsd_license_template % ( \ 832"""Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 833(C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM") 834 835 836 def printRealHeader(self): 837 print """ 838/** 839 * \\file 840 * Prototypes for indirect rendering functions. 841 * 842 * \\author Kevin E. Martin <kevin@precisioninsight.com> 843 * \\author Ian Romanick <idr@us.ibm.com> 844 */ 845 846#if !defined( _INDIRECT_H_ ) 847# define _INDIRECT_H_ 848 849""" 850 printVisibility( "HIDDEN", "hidden" ) 851 852 853 def printRealFooter(self): 854 print "# undef HIDDEN" 855 print "#endif /* !defined( _INDIRECT_H_ ) */" 856 857 def printFunction(self, f): 858 if f.fn_offset < 0 or f.ignore: return 859 print 'extern HIDDEN %s __indirect_gl%s(%s);' % (f.fn_return_type, f.name, f.get_parameter_string()) 860 861 862class PrintGlxSizeStubs(GlxProto): 863 def __init__(self): 864 GlxProto.__init__(self) 865 self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004", "IBM") 866 self.aliases = [] 867 self.glx_enum_sigs = {} 868 869 def printRealHeader(self): 870 print '' 871 print '#include <GL/gl.h>' 872 print '#include "indirect_size.h"' 873 874 print '' 875 printPure() 876 print '' 877 printFastcall() 878 print '' 879 printVisibility( "INTERNAL", "internal" ) 880 print '' 881 print '' 882 print '#ifdef HAVE_ALIAS' 883 print '# define ALIAS2(from,to) \\' 884 print ' INTERNAL PURE FASTCALL GLint __gl ## from ## _size( GLenum e ) \\' 885 print ' __attribute__ ((alias( # to )));' 886 print '# define ALIAS(from,to) ALIAS2( from, __gl ## to ## _size )' 887 print '#else' 888 print '# define ALIAS(from,to) \\' 889 print ' INTERNAL PURE FASTCALL GLint __gl ## from ## _size( GLenum e ) \\' 890 print ' { return __gl ## to ## _size( e ); }' 891 print '#endif' 892 print '' 893 print '' 894 895 def printRealFooter(self): 896 for a in self.aliases: 897 print a 898 899 def printFunction(self, f): 900 if self.glx_enum_functions.has_key(f.name): 901 ef = self.glx_enum_functions[f.name] 902 903 sig = ef.signature(); 904 if self.glx_enum_sigs.has_key(sig): 905 n = self.glx_enum_sigs[sig]; 906 a = 'ALIAS( %s, %s )' % (f.name, n) 907 self.aliases.append(a) 908 else: 909 ef.Print( f.name ) 910 self.glx_enum_sigs[sig] = f.name; 911 912 913 914class PrintGlxSizeStubs_h(GlxProto): 915 def __init__(self): 916 GlxProto.__init__(self) 917 self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004", "IBM") 918 self.aliases = [] 919 self.glx_enum_sigs = {} 920 921 def printRealHeader(self): 922 print """ 923/** 924 * \\file 925 * Prototypes for functions used to determine the number of data elements in 926 * various GLX protocol messages. 927 * 928 * \\author Ian Romanick <idr@us.ibm.com> 929 */ 930 931#if !defined( _GLXSIZE_H_ ) 932# define _GLXSIZE_H_ 933 934""" 935 printPure(); 936 print '' 937 printFastcall(); 938 print '' 939 printVisibility( "INTERNAL", "internal" ); 940 print '' 941 942 def printRealFooter(self): 943 print '' 944 print "# undef INTERNAL" 945 print "# undef PURE" 946 print "# undef FASTCALL" 947 print "#endif /* !defined( _GLXSIZE_H_ ) */" 948 949 950 def printFunction(self, f): 951 if self.glx_enum_functions.has_key(f.name): 952 ef = self.glx_enum_functions[f.name] 953 print 'extern INTERNAL PURE FASTCALL GLint __gl%s_size(GLenum);' % (f.name) 954 955 956def show_usage(): 957 print "Usage: %s [-f input_file_name] [-m output_mode]" % sys.argv[0] 958 sys.exit(1) 959 960 961if __name__ == '__main__': 962 file_name = "gl_API.xml" 963 964 try: 965 (args, trail) = getopt.getopt(sys.argv[1:], "f:m:") 966 except Exception,e: 967 show_usage() 968 969 mode = "proto" 970 for (arg,val) in args: 971 if arg == "-f": 972 file_name = val 973 elif arg == "-m": 974 mode = val 975 976 if mode == "proto": 977 dh = PrintGlxProtoStubs() 978 elif mode == "init_c": 979 dh = PrintGlxProtoInit_c() 980 elif mode == "init_h": 981 dh = PrintGlxProtoInit_h() 982 elif mode == "size_c": 983 dh = PrintGlxSizeStubs() 984 elif mode == "size_h": 985 dh = PrintGlxSizeStubs_h() 986 else: 987 show_usage() 988 989 parser = make_parser() 990 parser.setFeature(feature_namespaces, 0) 991 parser.setContentHandler(dh) 992 993 f = open(file_name) 994 995 dh.printHeader() 996 parser.parse(f) 997 dh.printFooter() 998