glX_proto_send.py revision 5f1f229f8da255ca9b390da1757ad781978cf619
1#!/usr/bin/python2 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 28from xml.sax import saxutils 29from xml.sax import make_parser 30from xml.sax.handler import feature_namespaces 31 32import gl_XML 33import glX_XML 34import license 35import sys, getopt, copy 36 37def hash_pixel_function(func): 38 """Generate a 'unique' key for a pixel function. The key is based on 39 the parameters written in the command packet. This includes any 40 padding that might be added for the original function and the 'NULL 41 image' flag.""" 42 43 [dim, junk, junk, junk, junk] = func.dimensions() 44 45 d = (dim + 1) & ~1 46 h = "%uD%uD_" % (d - 1, d) 47 48 for p in func.parameterIterator(1, 1): 49 h = "%s%u" % (h, p.size()) 50 51 if func.pad_after(p): 52 h += "4" 53 54 if func.image.img_null_flag: 55 h += "_NF" 56 57 n = func.name.replace("%uD" % (dim), "") 58 n = "__glx_%s_%uD%uD" % (n, d - 1, d) 59 return [h, n] 60 61 62class glXPixelFunctionUtility(glX_XML.glXFunction): 63 """Dummy class used to generate pixel "utility" functions that are 64 shared by multiple dimension image functions. For example, these 65 objects are used to generate shared functions used to send GLX 66 protocol for TexImage1D and TexImage2D, TexSubImage1D and 67 TexSubImage2D, etc.""" 68 69 def __init__(self, func, name): 70 # The parameters to the utility function are the same as the 71 # parameters to the real function except for the added "pad" 72 # parameters. 73 74 self.name = name 75 self.image = copy.copy(func.image) 76 self.fn_parameters = [] 77 for p in gl_XML.glFunction.parameterIterator(func): 78 self.fn_parameters.append(p) 79 80 pad_name = func.pad_after(p) 81 if pad_name: 82 pad = copy.copy(p) 83 pad.name = pad_name 84 self.fn_parameters.append(pad) 85 86 87 if self.image.height == None: 88 self.image.height = "height" 89 90 if self.image.img_yoff == None: 91 self.image.img_yoff = "yoffset" 92 93 if func.image.depth: 94 if self.image.extent == None: 95 self.image.extent = "extent" 96 97 if self.image.img_woff == None: 98 self.image.img_woff = "woffset" 99 100 101 self.set_return_type( func.fn_return_type ) 102 self.glx_rop = ~0 103 self.can_be_large = func.can_be_large 104 self.count_parameters = func.count_parameters 105 self.counter = func.counter 106 return 107 108 109class PrintGlxProtoStubs(glX_XML.GlxProto): 110 def __init__(self): 111 glX_XML.GlxProto.__init__(self) 112 self.last_category = "" 113 self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004, 2005", "IBM") 114 self.generic_sizes = [3, 4, 6, 8, 12, 16, 24, 32] 115 self.pixel_stubs = {} 116 return 117 118 def printRealHeader(self): 119 print '' 120 print '#include <GL/gl.h>' 121 print '#include "indirect.h"' 122 print '#include "glxclient.h"' 123 print '#include "indirect_size.h"' 124 print '#include <GL/glxproto.h>' 125 print '' 126 print '#define __GLX_PAD(n) (((n) + 3) & ~3)' 127 print '' 128 glX_XML.printFastcall() 129 glX_XML.printNoinline() 130 print '' 131 print '#if !defined __GNUC__ || __GNUC__ < 3' 132 print '# define __builtin_expect(x, y) x' 133 print '#endif' 134 print '' 135 print '/* If the size and opcode values are known at compile-time, this will, on' 136 print ' * x86 at least, emit them with a single instruction.' 137 print ' */' 138 print '#define emit_header(dest, op, size) \\' 139 print ' do { union { short s[2]; int i; } temp; \\' 140 print ' temp.s[0] = (size); temp.s[1] = (op); \\' 141 print ' *((int *)(dest)) = temp.i; } while(0)' 142 print '' 143 print """static NOINLINE CARD32 144read_reply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array ) 145{ 146 xGLXSingleReply reply; 147 148 (void) _XReply(dpy, (xReply *) & reply, 0, False); 149 if (size != 0) { 150 if ((reply.length > 0) || reply_is_always_array) { 151 const GLint bytes = (reply_is_always_array) 152 ? (4 * reply.length) : (reply.size * size); 153 const GLint extra = 4 - (bytes & 3); 154 155 _XRead(dpy, dest, bytes); 156 if ( extra < 4 ) { 157 _XEatData(dpy, extra); 158 } 159 } 160 else { 161 (void) memcpy( dest, &(reply.pad3), size); 162 } 163 } 164 165 return reply.retval; 166} 167 168#define X_GLXSingle 0 169 170static NOINLINE FASTCALL GLubyte * 171setup_single_request( __GLXcontext * gc, GLint sop, GLint cmdlen ) 172{ 173 xGLXSingleReq * req; 174 Display * const dpy = gc->currentDpy; 175 176 (void) __glXFlushRenderBuffer(gc, gc->pc); 177 LockDisplay(dpy); 178 GetReqExtra(GLXSingle, cmdlen, req); 179 req->reqType = gc->majorOpcode; 180 req->contextTag = gc->currentContextTag; 181 req->glxCode = sop; 182 return (GLubyte *)(req) + sz_xGLXSingleReq; 183} 184 185static NOINLINE FASTCALL GLubyte * 186setup_vendor_request( __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen ) 187{ 188 xGLXVendorPrivateReq * req; 189 Display * const dpy = gc->currentDpy; 190 191 (void) __glXFlushRenderBuffer(gc, gc->pc); 192 LockDisplay(dpy); 193 GetReqExtra(GLXVendorPrivate, cmdlen, req); 194 req->reqType = gc->majorOpcode; 195 req->glxCode = code; 196 req->vendorCode = vop; 197 req->contextTag = gc->currentContextTag; 198 return (GLubyte *)(req) + sz_xGLXVendorPrivateReq; 199} 200 201const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 }; 202 203#define zero (__glXDefaultPixelStore+0) 204#define one (__glXDefaultPixelStore+8) 205#define default_pixel_store_1D (__glXDefaultPixelStore+4) 206#define default_pixel_store_1D_size 20 207#define default_pixel_store_2D (__glXDefaultPixelStore+4) 208#define default_pixel_store_2D_size 20 209#define default_pixel_store_3D (__glXDefaultPixelStore+0) 210#define default_pixel_store_3D_size 36 211#define default_pixel_store_4D (__glXDefaultPixelStore+0) 212#define default_pixel_store_4D_size 36 213""" 214 215 for size in self.generic_sizes: 216 self.print_generic_function(size) 217 return 218 219 def printFunction(self, f): 220 if f.fn_offset < 0 or f.handcode or f.ignore: return 221 222 if f.glx_rop != 0 or f.vectorequiv != None: 223 if f.image: 224 self.printPixelFunction(f) 225 else: 226 self.printRenderFunction(f) 227 elif f.glx_sop != 0 or f.glx_vendorpriv != 0: 228 self.printSingleFunction(f) 229 else: 230 print "/* Missing GLX protocol for %s. */" % (f.name) 231 232 def print_generic_function(self, n): 233 size = (n + 3) & ~3 234 print """static FASTCALL NOINLINE void 235generic_%u_byte( GLint rop, const void * ptr ) 236{ 237 __GLXcontext * const gc = __glXGetCurrentContext(); 238 const GLuint cmdlen = %u; 239 240 emit_header(gc->pc, rop, cmdlen); 241 (void) memcpy((void *)(gc->pc + 4), ptr, %u); 242 gc->pc += cmdlen; 243 if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); } 244} 245""" % (n, size + 4, size) 246 247 248 def common_emit_one_arg(self, p, offset, pc, indent, adjust): 249 t = p.p_type 250 if p.is_array(): 251 src_ptr = p.name 252 else: 253 src_ptr = "&" + p.name 254 255 print '%s (void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \ 256 % (indent, pc, offset + adjust, src_ptr, p.size_string() ) 257 258 def common_emit_args(self, f, pc, indent, adjust, skip_vla): 259 offset = 0 260 261 if skip_vla: 262 r = 1 263 else: 264 r = 2 265 266 for p in f.parameterIterator(1, r): 267 self.common_emit_one_arg(p, offset, pc, indent, adjust) 268 offset += p.size() 269 270 return offset 271 272 273 def pixel_emit_args(self, f, pc, indent, adjust, dim, large): 274 """Emit the arguments for a pixel function. This differs from 275 common_emit_args in that pixel functions may require padding 276 be inserted (i.e., for the missing width field for 277 TexImage1D), and they may also require a 'NULL image' flag 278 be inserted before the image data.""" 279 280 offset = 0 281 for p in f.parameterIterator(1, 1): 282 self.common_emit_one_arg(p, offset, pc, indent, adjust) 283 offset += p.size() 284 285 if f.pad_after(p): 286 print '%s (void) memcpy((void *)(%s + %u), zero, 4);' % (indent, pc, offset + adjust) 287 offset += 4 288 289 if f.image.img_null_flag: 290 if large: 291 print '%s (void) memcpy((void *)(%s + %u), zero, 4);' % (indent, pc, offset + adjust) 292 else: 293 print '%s (void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (indent, pc, offset + adjust, f.image.name) 294 295 offset += 4 296 297 return offset 298 299 300 def large_emit_begin(self, indent, f, op_name = None): 301 if not op_name: 302 op_name = f.opcode_real_name() 303 304 print '%s const GLint op = %s;' % (indent, op_name) 305 print '%s const GLuint cmdlenLarge = cmdlen + 4;' % (indent) 306 print '%s GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);' % (indent) 307 print '%s (void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);' % (indent) 308 print '%s (void) memcpy((void *)(pc + 4), (void *)(&op), 4);' % (indent) 309 return 310 311 312 def common_func_print_just_header(self, f): 313 print '#define %s %d' % (f.opcode_name(), f.opcode_value()) 314 315 print '%s' % (f.fn_return_type) 316 print '__indirect_gl%s(%s)' % (f.name, f.get_parameter_string()) 317 print '{' 318 319 320 def common_func_print_just_start(self, f): 321 print ' __GLXcontext * const gc = __glXGetCurrentContext();' 322 323 # The only reason that single and vendor private commands need 324 # a variable called 'dpy' is becuase they use the SyncHandle 325 # macro. For whatever brain-dead reason, that macro is hard- 326 # coded to use a variable called 'dpy' instead of taking a 327 # parameter. 328 329 if not f.glx_rop: 330 print ' Display * const dpy = gc->currentDpy;' 331 skip_condition = "dpy != NULL" 332 elif f.can_be_large: 333 skip_condition = "gc->currentDpy != NULL" 334 else: 335 skip_condition = None 336 337 338 if f.fn_return_type != 'void': 339 print ' %s retval = (%s) 0;' % (f.fn_return_type, f.fn_return_type) 340 341 if f.count_parameters != None: 342 print ' const GLuint compsize = __gl%s_size(%s);' % (f.name, f.count_parameters) 343 elif f.image: 344 [dim, w, h, d, junk] = f.dimensions() 345 346 compsize = '__glImageSize(%s, %s, %s, %s, %s, %s)' % (w, h, d, f.image.img_format, f.image.img_type, f.image.img_target) 347 if not f.image.img_send_null: 348 compsize = '(%s != NULL) ? %s : 0' % (f.image.name, compsize) 349 350 print ' const GLuint compsize = %s;' % (compsize) 351 352 353 print ' const GLuint cmdlen = %s;' % (f.command_length()) 354 355 if f.counter: 356 if skip_condition: 357 skip_condition = "(%s >= 0) && (%s)" % (f.counter, skip_condition) 358 else: 359 skip_condition = "%s >= 0" % (f.counter) 360 361 362 if skip_condition: 363 print ' if (__builtin_expect(%s, 1)) {' % (skip_condition) 364 return 1 365 else: 366 return 0 367 368 369 def common_func_print_header(self, f): 370 self.common_func_print_just_header(f) 371 return self.common_func_print_just_start(f) 372 373 374 375 def printSingleFunction(self, f): 376 self.common_func_print_header(f) 377 378 if f.fn_parameters != []: 379 pc_decl = "GLubyte const * pc =" 380 else: 381 pc_decl = "(void)" 382 383 if f.glx_vendorpriv != 0: 384 print ' %s setup_vendor_request(gc, %s, %s, cmdlen);' % (pc_decl, f.opcode_real_name(), f.opcode_name()) 385 else: 386 print ' %s setup_single_request(gc, %s, cmdlen);' % (pc_decl, f.opcode_name()) 387 388 self.common_emit_args(f, "pc", " ", 0, 0) 389 390 if f.needs_reply(): 391 if f.output != None: 392 output_size = f.output.p_type.size 393 output_str = f.output.name 394 else: 395 output_size = 0 396 output_str = "NULL" 397 398 if f.fn_return_type != 'void': 399 return_str = " retval = (%s)" % (f.fn_return_type) 400 else: 401 return_str = " (void)" 402 403 if f.reply_always_array: 404 aa = "GL_TRUE" 405 else: 406 aa = "GL_FALSE" 407 408 print " %s read_reply(dpy, %s, %s, %s);" % (return_str, output_size, output_str, aa) 409 410 print ' UnlockDisplay(dpy); SyncHandle();' 411 print ' }' 412 print ' %s' % f.return_string() 413 print '}' 414 print '' 415 return 416 417 418 def printPixelFunction(self, f): 419 """This function could use some major refactoring. :(""" 420 421 # There is a code-space optimization that we can do here. 422 # Functions that are marked img_pad_dimensions have a version 423 # with an odd number of dimensions and an even number of 424 # dimensions. TexSubImage1D and TexSubImage2D are examples. 425 # We can emit a single function that does both, and have the 426 # real functions call the utility function with the correct 427 # parameters. 428 # 429 # The only quirk to this is that utility funcitons will be 430 # generated for 3D and 4D functions, but 4D (e.g., 431 # GL_SGIS_texture4D) isn't typically supported. This is 432 # probably not an issue. However, it would be possible to 433 # look at the total set of functions and determine if there 434 # is another function that would actually use the utility 435 # function. If not, then fallback to the normal way of 436 # generating code. 437 438 if f.image.img_pad_dimensions: 439 # Determine the hash key and the name for the utility 440 # function that is used to implement the real 441 # function. 442 443 [h, n] = hash_pixel_function(f) 444 445 446 # If the utility function is not yet known, generate 447 # it. 448 449 if not self.pixel_stubs.has_key(h): 450 self.pixel_stubs[h] = n 451 pixel_func = glXPixelFunctionUtility(f, n) 452 453 print 'static void' 454 print '%s( unsigned opcode, unsigned dim, %s )' % (n, pixel_func.get_parameter_string()) 455 print '{' 456 457 if self.common_func_print_just_start(pixel_func): 458 indent = " " 459 trailer = " }" 460 else: 461 indent = "" 462 trailer = None 463 464 465 if pixel_func.can_be_large: 466 print '%s if (cmdlen <= gc->maxSmallRenderCommandSize) {' % (indent) 467 print '%s if ( (gc->pc + cmdlen) > gc->bufEnd ) {' % (indent) 468 print '%s (void) __glXFlushRenderBuffer(gc, gc->pc);' % (indent) 469 print '%s }' % (indent) 470 indent += " " 471 472 [dim, width, height, depth, extent] = pixel_func.dimensions() 473 474 if dim < 3: 475 adjust = 20 + 4 476 else: 477 adjust = 36 + 4 478 479 480 print '%s emit_header(gc->pc, opcode, cmdlen);' % (indent) 481 482 offset = self.pixel_emit_args(pixel_func, "gc->pc", indent, adjust, dim, 0) 483 484 [s, junk] = pixel_func.command_payload_length() 485 486 pixHeaderPtr = "gc->pc + 4" 487 pcPtr = "gc->pc + %u" % (s + 4) 488 489 if pixel_func.image.img_send_null: 490 condition = '(compsize > 0) && (%s != NULL)' % (pixel_func.image.name) 491 else: 492 condition = 'compsize > 0' 493 494 print '%s if (%s) {' % (indent, condition) 495 print '%s (*gc->fillImage)(gc, dim, %s, %s, %s, %s, %s, %s, %s, %s);' % (indent, width, height, depth, pixel_func.image.img_format, pixel_func.image.img_type, pixel_func.image.name, pcPtr, pixHeaderPtr) 496 print '%s }' % (indent) 497 print '%s else {' % (indent) 498 print '%s (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (indent, pixHeaderPtr, dim, dim) 499 print '%s }' % (indent) 500 501 print '%s gc->pc += cmdlen;' % (indent) 502 print '%s if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent) 503 504 if f.can_be_large: 505 adjust += 4 506 507 print '%s}' % (indent) 508 print '%selse {' % (indent) 509 510 self.large_emit_begin(indent, pixel_func, "opcode") 511 offset = self.pixel_emit_args(pixel_func, "pc", indent, adjust, dim, 1) 512 513 pixHeaderPtr = "pc + 8" 514 pcPtr = "pc + %u" % (s + 8) 515 516 print '%s __glXSendLargeImage(gc, compsize, dim, %s, %s, %s, %s, %s, %s, %s, %s);' % (indent, width, height, depth, f.image.img_format, f.image.img_type, f.image.name, pcPtr, pixHeaderPtr) 517 518 print '%s}' % (indent) 519 520 if trailer: print trailer 521 print '}' 522 print '' 523 524 525 526 # Generate the real function as a call to the 527 # utility function. 528 529 self.common_func_print_just_header(f) 530 531 [dim, junk, junk, junk, junk] = f.dimensions() 532 533 p_string = "" 534 for p in gl_XML.glFunction.parameterIterator(f): 535 p_string += ", " + p.name 536 537 if f.pad_after(p): 538 p_string += ", 1" 539 540 print ' %s(%s, %u%s );' % (n, f.opcode_name(), dim, p_string) 541 print '}' 542 print '' 543 return 544 545 546 if self.common_func_print_header(f): 547 indent = " " 548 trailer = " }" 549 else: 550 indent = "" 551 trailer = None 552 553 554 if f.can_be_large: 555 print '%s if (cmdlen <= gc->maxSmallRenderCommandSize) {' % (indent) 556 print '%s if ( (gc->pc + cmdlen) > gc->bufEnd ) {' % (indent) 557 print '%s (void) __glXFlushRenderBuffer(gc, gc->pc);' % (indent) 558 print '%s }' % (indent) 559 indent += " " 560 561 [dim, width, height, depth, extent] = f.dimensions() 562 563 if dim < 3: 564 adjust = 20 + 4 565 else: 566 adjust = 36 + 4 567 568 569 print '%s emit_header(gc->pc, %s, cmdlen);' % (indent, f.opcode_real_name()) 570 571 offset = self.pixel_emit_args(f, "gc->pc", indent, adjust, dim, 0) 572 573 [s, junk] = f.command_payload_length() 574 575 pixHeaderPtr = "gc->pc + 4" 576 pcPtr = "gc->pc + %u" % (s + 4) 577 578 if f.image.img_send_null: 579 condition = '(compsize > 0) && (%s != NULL)' % (f.image.name) 580 else: 581 condition = 'compsize > 0' 582 583 print '%s if (%s) {' % (indent, condition) 584 print '%s (*gc->fillImage)(gc, %u, %s, %s, %s, %s, %s, %s, %s, %s);' % (indent, dim, width, height, depth, f.image.img_format, f.image.img_type, f.image.name, pcPtr, pixHeaderPtr) 585 print '%s }' % (indent) 586 print '%s else {' % (indent) 587 print '%s (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (indent, pixHeaderPtr, dim, dim) 588 print '%s }' % (indent) 589 590 print '%s gc->pc += cmdlen;' % (indent) 591 print '%s if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent) 592 593 if f.can_be_large: 594 adjust += 4 595 596 print '%s}' % (indent) 597 print '%selse {' % (indent) 598 599 self.large_emit_begin(indent, f) 600 offset = self.pixel_emit_args(f, "pc", indent, adjust, dim, 1) 601 602 pixHeaderPtr = "pc + 8" 603 pcPtr = "pc + %u" % (s + 8) 604 605 print '%s __glXSendLargeImage(gc, compsize, %u, %s, %s, %s, %s, %s, %s, %s, %s);' % (indent, dim, width, height, depth, f.image.img_format, f.image.img_type, f.image.name, pcPtr, pixHeaderPtr) 606 607 print '%s}' % (indent) 608 609 if trailer: print trailer 610 print '}' 611 print '' 612 return 613 614 615 def printRenderFunction(self, f): 616 # There is a class of GL functions that take a single pointer 617 # as a parameter. This pointer points to a fixed-size chunk 618 # of data, and the protocol for this functions is very 619 # regular. Since they are so regular and there are so many 620 # of them, special case them with generic functions. On 621 # x86, this saves about 26KB in the libGL.so binary. 622 623 if f.variable_length_parameter() == None and len(f.fn_parameters) == 1: 624 p = f.fn_parameters[0] 625 if p.is_pointer: 626 [cmdlen, size_string] = f.command_payload_length() 627 if cmdlen in self.generic_sizes: 628 self.common_func_print_just_header(f) 629 print ' generic_%u_byte( %s, %s );' % (cmdlen, f.opcode_real_name(), p.name) 630 print '}' 631 print '' 632 return 633 634 if self.common_func_print_header(f): 635 indent = " " 636 trailer = " }" 637 else: 638 indent = "" 639 trailer = None 640 641 if f.can_be_large: 642 print '%s if (cmdlen <= gc->maxSmallRenderCommandSize) {' % (indent) 643 print '%s if ( (gc->pc + cmdlen) > gc->bufEnd ) {' % (indent) 644 print '%s (void) __glXFlushRenderBuffer(gc, gc->pc);' % (indent) 645 print '%s }' % (indent) 646 indent += " " 647 648 print '%s emit_header(gc->pc, %s, cmdlen);' % (indent, f.opcode_real_name()) 649 650 self.common_emit_args(f, "gc->pc", indent, 4, 0) 651 print '%s gc->pc += cmdlen;' % (indent) 652 print '%s if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent) 653 654 if f.can_be_large: 655 print '%s}' % (indent) 656 print '%selse {' % (indent) 657 658 self.large_emit_begin(indent, f) 659 offset = self.common_emit_args(f, "pc", indent, 8, 1) 660 661 p = f.variable_length_parameter() 662 print '%s __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (indent, offset + 8, p.name, p.size_string()) 663 print '%s}' % (indent) 664 665 if trailer: print trailer 666 print '}' 667 print '' 668 return 669 670 671class PrintGlxProtoInit_c(glX_XML.GlxProto): 672 def __init__(self): 673 glX_XML.GlxProto.__init__(self) 674 self.last_category = "" 675 self.license = license.bsd_license_template % ( \ 676"""Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 677(C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM") 678 679 680 def printRealHeader(self): 681 print """/** 682 * \\file indirect_init.c 683 * Initialize indirect rendering dispatch table. 684 * 685 * \\author Kevin E. Martin <kevin@precisioninsight.com> 686 * \\author Brian Paul <brian@precisioninsight.com> 687 * \\author Ian Romanick <idr@us.ibm.com> 688 */ 689 690#include "indirect_init.h" 691#include "indirect.h" 692#include "glapi.h" 693 694 695/** 696 * No-op function used to initialize functions that have no GLX protocol 697 * support. 698 */ 699static int NoOp(void) 700{ 701 return 0; 702} 703 704/** 705 * Create and initialize a new GL dispatch table. The table is initialized 706 * with GLX indirect rendering protocol functions. 707 */ 708__GLapi * __glXNewIndirectAPI( void ) 709{ 710 __GLapi *glAPI; 711 GLuint entries; 712 713 entries = _glapi_get_dispatch_table_size(); 714 glAPI = (__GLapi *) Xmalloc(entries * sizeof(void *)); 715 716 /* first, set all entries to point to no-op functions */ 717 { 718 int i; 719 void **dispatch = (void **) glAPI; 720 for (i = 0; i < entries; i++) { 721 dispatch[i] = (void *) NoOp; 722 } 723 } 724 725 /* now, initialize the entries we understand */""" 726 727 def printRealFooter(self): 728 print """ 729 return glAPI; 730} 731""" 732 733 def printFunction(self, f): 734 if f.fn_offset < 0 or f.ignore: return 735 736 if f.category != self.last_category: 737 self.last_category = f.category 738 print '' 739 print ' /* %s */' % (self.last_category) 740 print '' 741 742 print ' glAPI->%s = __indirect_gl%s;' % (f.name, f.name) 743 744 745class PrintGlxProtoInit_h(glX_XML.GlxProto): 746 def __init__(self): 747 glX_XML.GlxProto.__init__(self) 748 self.last_category = "" 749 self.license = license.bsd_license_template % ( \ 750"""Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 751(C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM") 752 753 754 def printRealHeader(self): 755 print """ 756/** 757 * \\file 758 * Prototypes for indirect rendering functions. 759 * 760 * \\author Kevin E. Martin <kevin@precisioninsight.com> 761 * \\author Ian Romanick <idr@us.ibm.com> 762 */ 763 764#if !defined( _INDIRECT_H_ ) 765# define _INDIRECT_H_ 766 767""" 768 glX_XML.printVisibility( "HIDDEN", "hidden" ) 769 770 771 def printRealFooter(self): 772 print "# undef HIDDEN" 773 print "#endif /* !defined( _INDIRECT_H_ ) */" 774 775 def printFunction(self, f): 776 if f.fn_offset < 0 or f.ignore: return 777 print 'extern HIDDEN %s __indirect_gl%s(%s);' % (f.fn_return_type, f.name, f.get_parameter_string()) 778 779 780class PrintGlxSizeStubs(glX_XML.GlxProto): 781 def __init__(self): 782 glX_XML.GlxProto.__init__(self) 783 self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004", "IBM") 784 self.aliases = [] 785 self.glx_enum_sigs = {} 786 787 def printRealHeader(self): 788 print '' 789 print '#include <GL/gl.h>' 790 print '#include "indirect_size.h"' 791 792 print '' 793 glX_XML.printPure() 794 print '' 795 glX_XML.printFastcall() 796 print '' 797 glX_XML.printVisibility( "INTERNAL", "internal" ) 798 print '' 799 print '' 800 print '#ifdef HAVE_ALIAS' 801 print '# define ALIAS2(from,to) \\' 802 print ' INTERNAL PURE FASTCALL GLint __gl ## from ## _size( GLenum e ) \\' 803 print ' __attribute__ ((alias( # to )));' 804 print '# define ALIAS(from,to) ALIAS2( from, __gl ## to ## _size )' 805 print '#else' 806 print '# define ALIAS(from,to) \\' 807 print ' INTERNAL PURE FASTCALL GLint __gl ## from ## _size( GLenum e ) \\' 808 print ' { return __gl ## to ## _size( e ); }' 809 print '#endif' 810 print '' 811 print '' 812 813 def printRealFooter(self): 814 for a in self.aliases: 815 print a 816 817 def printFunction(self, f): 818 if self.glx_enum_functions.has_key(f.name): 819 ef = self.glx_enum_functions[f.name] 820 821 sig = ef.signature(); 822 if self.glx_enum_sigs.has_key(sig): 823 n = self.glx_enum_sigs[sig]; 824 a = 'ALIAS( %s, %s )' % (f.name, n) 825 self.aliases.append(a) 826 else: 827 ef.Print( f.name ) 828 self.glx_enum_sigs[sig] = f.name; 829 830 831 832class PrintGlxSizeStubs_h(glX_XML.GlxProto): 833 def __init__(self): 834 glX_XML.GlxProto.__init__(self) 835 self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004", "IBM") 836 self.aliases = [] 837 self.glx_enum_sigs = {} 838 839 def printRealHeader(self): 840 print """ 841/** 842 * \\file 843 * Prototypes for functions used to determine the number of data elements in 844 * various GLX protocol messages. 845 * 846 * \\author Ian Romanick <idr@us.ibm.com> 847 */ 848 849#if !defined( _GLXSIZE_H_ ) 850# define _GLXSIZE_H_ 851 852""" 853 glX_XML.printPure(); 854 print '' 855 glX_XML.printFastcall(); 856 print '' 857 glX_XML.printVisibility( "INTERNAL", "internal" ); 858 print '' 859 860 def printRealFooter(self): 861 print '' 862 print "# undef INTERNAL" 863 print "# undef PURE" 864 print "# undef FASTCALL" 865 print "#endif /* !defined( _GLXSIZE_H_ ) */" 866 867 868 def printFunction(self, f): 869 if self.glx_enum_functions.has_key(f.name): 870 ef = self.glx_enum_functions[f.name] 871 print 'extern INTERNAL PURE FASTCALL GLint __gl%s_size(GLenum);' % (f.name) 872 873 874def show_usage(): 875 print "Usage: %s [-f input_file_name] [-m output_mode]" % sys.argv[0] 876 sys.exit(1) 877 878 879if __name__ == '__main__': 880 file_name = "gl_API.xml" 881 882 try: 883 (args, trail) = getopt.getopt(sys.argv[1:], "f:m:") 884 except Exception,e: 885 show_usage() 886 887 mode = "proto" 888 for (arg,val) in args: 889 if arg == "-f": 890 file_name = val 891 elif arg == "-m": 892 mode = val 893 894 if mode == "proto": 895 dh = PrintGlxProtoStubs() 896 elif mode == "init_c": 897 dh = PrintGlxProtoInit_c() 898 elif mode == "init_h": 899 dh = PrintGlxProtoInit_h() 900 elif mode == "size_c": 901 dh = PrintGlxSizeStubs() 902 elif mode == "size_h": 903 dh = PrintGlxSizeStubs_h() 904 else: 905 show_usage() 906 907 parser = make_parser() 908 parser.setFeature(feature_namespaces, 0) 909 parser.setContentHandler(dh) 910 911 f = open(file_name) 912 913 dh.printHeader() 914 parser.parse(f) 915 dh.printFooter() 916