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>
28 from xml
.sax
import saxutils
29 from xml
.sax
import make_parser
30 from xml
.sax
.handler
import feature_namespaces
35 import sys
, getopt
, copy
37 def 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
43 [dim
, junk
, junk
, junk
, junk
] = func
.dimensions()
46 h
= "%uD%uD_" % (d
- 1, d
)
48 for p
in func
.parameterIterator(1, 1):
49 h
= "%s%u" % (h
, p
.size())
54 if func
.image
.img_null_flag
:
57 n
= func
.name
.replace("%uD" % (dim
), "")
58 n
= "__glx_%s_%uD%uD" % (n
, d
- 1, d
)
62 class 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."""
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"
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
)
80 pad_name
= func
.pad_after(p
)
84 self
.fn_parameters
.append(pad
)
87 if self
.image
.height
== None:
88 self
.image
.height
= "height"
90 if self
.image
.img_yoff
== None:
91 self
.image
.img_yoff
= "yoffset"
94 if self
.image
.extent
== None:
95 self
.image
.extent
= "extent"
97 if self
.image
.img_woff
== None:
98 self
.image
.img_woff
= "woffset"
101 self
.set_return_type( func
.fn_return_type
)
103 self
.can_be_large
= func
.can_be_large
104 self
.count_parameter_list
= func
.count_parameter_list
105 self
.counter
= func
.counter
106 self
.img_reset
= None
110 class PrintGlxProtoStubs(glX_XML
.GlxProto
):
112 glX_XML
.GlxProto
.__init
__(self
)
113 self
.last_category
= ""
114 self
.license
= license
.bsd_license_template
% ( "(C) Copyright IBM Corporation 2004, 2005", "IBM")
115 self
.generic_sizes
= [3, 4, 6, 8, 12, 16, 24, 32]
116 self
.pixel_stubs
= {}
120 def printRealHeader(self
):
122 print '#include <GL/gl.h>'
123 print '#include "indirect.h"'
124 print '#include "glxclient.h"'
125 print '#include "indirect_size.h"'
126 print '#include <GL/glxproto.h>'
128 print '#define __GLX_PAD(n) (((n) + 3) & ~3)'
133 print '#if !defined __GNUC__ || __GNUC__ < 3'
134 print '# define __builtin_expect(x, y) x'
137 print '/* If the size and opcode values are known at compile-time, this will, on'
138 print ' * x86 at least, emit them with a single instruction.'
140 print '#define emit_header(dest, op, size) \\'
141 print ' do { union { short s[2]; int i; } temp; \\'
142 print ' temp.s[0] = (size); temp.s[1] = (op); \\'
143 print ' *((int *)(dest)) = temp.i; } while(0)'
145 print """NOINLINE CARD32
146 __glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array )
148 xGLXSingleReply reply;
150 (void) _XReply(dpy, (xReply *) & reply, 0, False);
152 if ((reply.length > 0) || reply_is_always_array) {
153 const GLint bytes = (reply_is_always_array)
154 ? (4 * reply.length) : (reply.size * size);
155 const GLint extra = 4 - (bytes & 3);
157 _XRead(dpy, dest, bytes);
159 _XEatData(dpy, extra);
163 (void) memcpy( dest, &(reply.pad3), size);
171 __glXReadPixelReply( Display *dpy, __GLXcontext * gc, unsigned max_dim,
172 GLint width, GLint height, GLint depth, GLenum format, GLenum type,
173 void * dest, GLboolean dimensions_in_reply )
175 xGLXSingleReply reply;
178 (void) _XReply(dpy, (xReply *) & reply, 0, False);
180 if ( dimensions_in_reply ) {
185 if ((height == 0) || (max_dim < 2)) { height = 1; }
186 if ((depth == 0) || (max_dim < 3)) { depth = 1; }
189 size = reply.length * 4;
191 void * buf = Xmalloc( size );
194 _XEatData(dpy, size);
195 __glXSetError(gc, GL_OUT_OF_MEMORY);
198 const GLint extra = 4 - (size & 3);
200 _XRead(dpy, buf, size);
202 _XEatData(dpy, extra);
205 __glEmptyImage(gc, 3, width, height, depth, format, type,
212 #define X_GLXSingle 0
214 NOINLINE FASTCALL GLubyte *
215 __glXSetupSingleRequest( __GLXcontext * gc, GLint sop, GLint cmdlen )
218 Display * const dpy = gc->currentDpy;
220 (void) __glXFlushRenderBuffer(gc, gc->pc);
222 GetReqExtra(GLXSingle, cmdlen, req);
223 req->reqType = gc->majorOpcode;
224 req->contextTag = gc->currentContextTag;
226 return (GLubyte *)(req) + sz_xGLXSingleReq;
229 NOINLINE FASTCALL GLubyte *
230 __glXSetupVendorRequest( __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen )
232 xGLXVendorPrivateReq * req;
233 Display * const dpy = gc->currentDpy;
235 (void) __glXFlushRenderBuffer(gc, gc->pc);
237 GetReqExtra(GLXVendorPrivate, cmdlen, req);
238 req->reqType = gc->majorOpcode;
240 req->vendorCode = vop;
241 req->contextTag = gc->currentContextTag;
242 return (GLubyte *)(req) + sz_xGLXVendorPrivateReq;
245 const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 };
247 #define zero (__glXDefaultPixelStore+0)
248 #define one (__glXDefaultPixelStore+8)
249 #define default_pixel_store_1D (__glXDefaultPixelStore+4)
250 #define default_pixel_store_1D_size 20
251 #define default_pixel_store_2D (__glXDefaultPixelStore+4)
252 #define default_pixel_store_2D_size 20
253 #define default_pixel_store_3D (__glXDefaultPixelStore+0)
254 #define default_pixel_store_3D_size 36
255 #define default_pixel_store_4D (__glXDefaultPixelStore+0)
256 #define default_pixel_store_4D_size 36
259 for size
in self
.generic_sizes
:
260 self
.print_generic_function(size
)
263 def printFunction(self
, f
):
264 if f
.client_handcode
: return
266 if f
.glx_rop
!= 0 or f
.vectorequiv
!= None:
268 self
.printPixelFunction(f
)
270 self
.printRenderFunction(f
)
271 elif f
.glx_sop
!= 0 or f
.glx_vendorpriv
!= 0:
272 self
.printSingleFunction(f
)
274 print "/* Missing GLX protocol for %s. */" % (f
.name
)
276 def print_generic_function(self
, n
):
278 print """static FASTCALL NOINLINE void
279 generic_%u_byte( GLint rop, const void * ptr )
281 __GLXcontext * const gc = __glXGetCurrentContext();
282 const GLuint cmdlen = %u;
284 emit_header(gc->pc, rop, cmdlen);
285 (void) memcpy((void *)(gc->pc + 4), ptr, %u);
287 if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }
289 """ % (n
, size
+ 4, size
)
292 def common_emit_one_arg(self
, p
, offset
, pc
, indent
, adjust
):
297 src_ptr
= "&" + p
.name
299 print '%s (void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
300 % (indent
, pc
, offset
+ adjust
, src_ptr
, p
.size_string() )
302 def common_emit_args(self
, f
, pc
, indent
, adjust
, skip_vla
):
310 for p
in f
.parameterIterator(1, r
):
311 if p
.name
!= f
.img_reset
:
312 self
.common_emit_one_arg(p
, offset
, pc
, indent
, adjust
)
318 def pixel_emit_args(self
, f
, pc
, indent
, adjust
, dim
, large
):
319 """Emit the arguments for a pixel function. This differs from
320 common_emit_args in that pixel functions may require padding
321 be inserted (i.e., for the missing width field for
322 TexImage1D), and they may also require a 'NULL image' flag
323 be inserted before the image data."""
326 for p
in f
.parameterIterator(1, 1):
327 self
.common_emit_one_arg(p
, offset
, pc
, indent
, adjust
)
331 print '%s (void) memcpy((void *)(%s + %u), zero, 4);' % (indent
, pc
, offset
+ adjust
)
334 if f
.image
.img_null_flag
:
336 print '%s (void) memcpy((void *)(%s + %u), zero, 4);' % (indent
, pc
, offset
+ adjust
)
338 print '%s (void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (indent
, pc
, offset
+ adjust
, f
.image
.name
)
345 def large_emit_begin(self
, indent
, f
, op_name
= None):
347 op_name
= f
.opcode_real_name()
349 print '%s const GLint op = %s;' % (indent
, op_name
)
350 print '%s const GLuint cmdlenLarge = cmdlen + 4;' % (indent
)
351 print '%s GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);' % (indent
)
352 print '%s (void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);' % (indent
)
353 print '%s (void) memcpy((void *)(pc + 4), (void *)(&op), 4);' % (indent
)
357 def common_func_print_just_header(self
, f
):
358 print '#define %s %d' % (f
.opcode_name(), f
.opcode_value())
360 print '%s' % (f
.fn_return_type
)
361 print '__indirect_gl%s(%s)' % (f
.name
, f
.get_parameter_string())
365 def common_func_print_just_start(self
, f
):
366 print ' __GLXcontext * const gc = __glXGetCurrentContext();'
368 # The only reason that single and vendor private commands need
369 # a variable called 'dpy' is becuase they use the SyncHandle
370 # macro. For whatever brain-dead reason, that macro is hard-
371 # coded to use a variable called 'dpy' instead of taking a
375 if f
.image
and f
.image
.is_output
:
376 print ' const __GLXattribute * const state = gc->client_state_private;'
378 print ' Display * const dpy = gc->currentDpy;'
379 skip_condition
= "dpy != NULL"
381 skip_condition
= "gc->currentDpy != NULL"
383 skip_condition
= None
386 if f
.fn_return_type
!= 'void':
387 print ' %s retval = (%s) 0;' % (f
.fn_return_type
, f
.fn_return_type
)
389 if not f
.output_parameter():
390 compsize
= self
.size_call( f
)
392 print ' const GLuint compsize = %s;' % (compsize
)
394 print ' const GLuint cmdlen = %s;' % (f
.command_length())
398 skip_condition
= "(%s >= 0) && (%s)" % (f
.counter
, skip_condition
)
400 skip_condition
= "%s >= 0" % (f
.counter
)
404 print ' if (__builtin_expect(%s, 1)) {' % (skip_condition
)
410 def common_func_print_header(self
, f
):
411 self
.common_func_print_just_header(f
)
412 return self
.common_func_print_just_start(f
)
416 def printSingleFunction(self
, f
):
417 self
.common_func_print_header(f
)
420 print ' printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
422 if f
.fn_parameters
!= []:
423 pc_decl
= "GLubyte const * pc ="
427 if f
.glx_vendorpriv
!= 0:
428 print ' %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl
, f
.opcode_real_name(), f
.opcode_name())
430 print ' %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl
, f
.opcode_name())
432 self
.common_emit_args(f
, "pc", " ", 0, 0)
433 if f
.image
and f
.image
.is_output
:
434 o
= f
.command_fixed_length() - 4
435 print ' *(int32_t *)(pc + %u) = 0;' % (o
)
436 if f
.image
.img_format
!= "GL_COLOR_INDEX" or f
.image
.img_type
!= "GL_BITMAP":
437 print ' * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o
)
440 print ' * (int8_t *)(pc + %u) = %s;' % (o
+ 1, f
.img_reset
)
444 if f
.image
and f
.image
.is_output
:
445 [dim
, w
, h
, d
, junk
] = f
.dimensions()
446 if f
.dimensions_in_reply
:
447 print " __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim
, f
.image
.img_format
, f
.image
.img_type
, f
.image
.name
)
449 print " __glXReadPixelReply(dpy, gc, %u, %s, %s, %s, %s, %s, %s, GL_FALSE);" % (dim
, w
, h
, d
, f
.image
.img_format
, f
.image
.img_type
, f
.image
.name
)
452 output_size
= f
.output
.p_type
.size
453 output_str
= f
.output
.name
458 if f
.fn_return_type
!= 'void':
459 return_str
= " retval = (%s)" % (f
.fn_return_type
)
461 return_str
= " (void)"
463 if f
.reply_always_array
:
468 print " %s __glXReadReply(dpy, %s, %s, %s);" % (return_str
, output_size
, output_str
, aa
)
471 # Only emit the extra glFinish call for functions
472 # that don't already require a reply from the server.
473 print ' __indirect_glFinish();'
476 print ' printf( "Exit %%s.\\n", "gl%s" );' % (f
.name
)
479 print ' UnlockDisplay(dpy); SyncHandle();'
481 print ' %s' % f
.return_string()
487 def printPixelFunction(self
, f
):
488 """This function could use some major refactoring. :("""
490 # There is a code-space optimization that we can do here.
491 # Functions that are marked img_pad_dimensions have a version
492 # with an odd number of dimensions and an even number of
493 # dimensions. TexSubImage1D and TexSubImage2D are examples.
494 # We can emit a single function that does both, and have the
495 # real functions call the utility function with the correct
498 # The only quirk to this is that utility funcitons will be
499 # generated for 3D and 4D functions, but 4D (e.g.,
500 # GL_SGIS_texture4D) isn't typically supported. This is
501 # probably not an issue. However, it would be possible to
502 # look at the total set of functions and determine if there
503 # is another function that would actually use the utility
504 # function. If not, then fallback to the normal way of
507 if f
.image
.img_pad_dimensions
:
508 # Determine the hash key and the name for the utility
509 # function that is used to implement the real
512 [h
, n
] = hash_pixel_function(f
)
515 # If the utility function is not yet known, generate
518 if not self
.pixel_stubs
.has_key(h
):
519 self
.pixel_stubs
[h
] = n
520 pixel_func
= glXPixelFunctionUtility(f
, n
)
523 print '%s( unsigned opcode, unsigned dim, %s )' % (n
, pixel_func
.get_parameter_string())
526 if self
.common_func_print_just_start(pixel_func
):
534 if pixel_func
.can_be_large
:
535 print '%s if (cmdlen <= gc->maxSmallRenderCommandSize) {' % (indent
)
536 print '%s if ( (gc->pc + cmdlen) > gc->bufEnd ) {' % (indent
)
537 print '%s (void) __glXFlushRenderBuffer(gc, gc->pc);' % (indent
)
538 print '%s }' % (indent
)
541 [dim
, width
, height
, depth
, extent
] = pixel_func
.dimensions()
542 adjust
= pixel_func
.offset_of_first_parameter() + 4
544 print '%s emit_header(gc->pc, opcode, cmdlen);' % (indent
)
546 offset
= self
.pixel_emit_args(pixel_func
, "gc->pc", indent
, adjust
, dim
, 0)
548 s
= pixel_func
.command_fixed_length()
550 pixHeaderPtr
= "gc->pc + 4"
551 pcPtr
= "gc->pc + %u" % (s
+ 4)
553 if pixel_func
.image
.img_send_null
:
554 condition
= '(compsize > 0) && (%s != NULL)' % (pixel_func
.image
.name
)
556 condition
= 'compsize > 0'
558 print '%s if (%s) {' % (indent
, condition
)
559 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
)
560 print '%s }' % (indent
)
561 print '%s else {' % (indent
)
562 print '%s (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (indent
, pixHeaderPtr
, dim
, dim
)
563 print '%s }' % (indent
)
565 print '%s gc->pc += cmdlen;' % (indent
)
566 print '%s if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent
)
571 print '%s}' % (indent
)
572 print '%selse {' % (indent
)
574 self
.large_emit_begin(indent
, pixel_func
, "opcode")
575 offset
= self
.pixel_emit_args(pixel_func
, "pc", indent
, adjust
, dim
, 1)
577 pixHeaderPtr
= "pc + 8"
578 pcPtr
= "pc + %u" % (s
+ 8)
580 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
)
582 print '%s}' % (indent
)
584 if trailer
: print trailer
590 # Generate the real function as a call to the
593 self
.common_func_print_just_header(f
)
595 [dim
, junk
, junk
, junk
, junk
] = f
.dimensions()
598 for p
in gl_XML
.glFunction
.parameterIterator(f
):
599 p_string
+= ", " + p
.name
604 print ' %s(%s, %u%s );' % (n
, f
.opcode_name(), dim
, p_string
)
610 if self
.common_func_print_header(f
):
619 print '%s if (cmdlen <= gc->maxSmallRenderCommandSize) {' % (indent
)
620 print '%s if ( (gc->pc + cmdlen) > gc->bufEnd ) {' % (indent
)
621 print '%s (void) __glXFlushRenderBuffer(gc, gc->pc);' % (indent
)
622 print '%s }' % (indent
)
625 [dim
, width
, height
, depth
, extent
] = f
.dimensions()
626 adjust
= f
.offset_of_first_parameter() + 4
628 print '%s emit_header(gc->pc, %s, cmdlen);' % (indent
, f
.opcode_real_name())
630 offset
= self
.pixel_emit_args(f
, "gc->pc", indent
, adjust
, dim
, 0)
632 s
= f
.command_fixed_length()
634 pixHeaderPtr
= "gc->pc + 4"
635 pcPtr
= "gc->pc + %u" % (s
+ 4)
637 if f
.image
.img_send_null
:
638 condition
= '(compsize > 0) && (%s != NULL)' % (f
.image
.name
)
640 condition
= 'compsize > 0'
642 print '%s if (%s) {' % (indent
, condition
)
643 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
)
644 print '%s }' % (indent
)
645 print '%s else {' % (indent
)
646 print '%s (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (indent
, pixHeaderPtr
, dim
, dim
)
647 print '%s }' % (indent
)
649 print '%s gc->pc += cmdlen;' % (indent
)
650 print '%s if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent
)
655 print '%s}' % (indent
)
656 print '%selse {' % (indent
)
658 self
.large_emit_begin(indent
, f
)
659 offset
= self
.pixel_emit_args(f
, "pc", indent
, adjust
, dim
, 1)
661 pixHeaderPtr
= "pc + 8"
662 pcPtr
= "pc + %u" % (s
+ 8)
664 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
)
666 print '%s}' % (indent
)
668 if trailer
: print trailer
674 def printRenderFunction(self
, f
):
675 # There is a class of GL functions that take a single pointer
676 # as a parameter. This pointer points to a fixed-size chunk
677 # of data, and the protocol for this functions is very
678 # regular. Since they are so regular and there are so many
679 # of them, special case them with generic functions. On
680 # x86, this saves about 26KB in the libGL.so binary.
682 if f
.variable_length_parameter() == None and len(f
.fn_parameters
) == 1:
683 p
= f
.fn_parameters
[0]
685 cmdlen
= f
.command_fixed_length()
686 if cmdlen
in self
.generic_sizes
:
687 self
.common_func_print_just_header(f
)
688 print ' generic_%u_byte( %s, %s );' % (cmdlen
, f
.opcode_real_name(), p
.name
)
693 if self
.common_func_print_header(f
):
701 print '%s printf( "Enter %%s...\\n", "gl%s" );' % (indent
, f
.name
)
704 print '%s if (cmdlen <= gc->maxSmallRenderCommandSize) {' % (indent
)
705 print '%s if ( (gc->pc + cmdlen) > gc->bufEnd ) {' % (indent
)
706 print '%s (void) __glXFlushRenderBuffer(gc, gc->pc);' % (indent
)
707 print '%s }' % (indent
)
710 print '%s emit_header(gc->pc, %s, cmdlen);' % (indent
, f
.opcode_real_name())
712 self
.common_emit_args(f
, "gc->pc", indent
, 4, 0)
713 print '%s gc->pc += cmdlen;' % (indent
)
714 print '%s if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent
)
717 print '%s}' % (indent
)
718 print '%selse {' % (indent
)
720 self
.large_emit_begin(indent
, f
)
721 offset
= self
.common_emit_args(f
, "pc", indent
, 8, 1)
723 p
= f
.variable_length_parameter()
724 print '%s __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (indent
, offset
+ 8, p
.name
, p
.size_string())
725 print '%s}' % (indent
)
728 print '%s __indirect_glFinish();' % (indent
)
729 print '%s printf( "Exit %%s.\\n", "gl%s" );' % (indent
, f
.name
)
731 if trailer
: print trailer
737 class PrintGlxProtoInit_c(glX_XML
.GlxProto
):
739 glX_XML
.GlxProto
.__init
__(self
)
740 self
.last_category
= ""
741 self
.license
= license
.bsd_license_template
% ( \
742 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
743 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
746 def printRealHeader(self
):
748 * \\file indirect_init.c
749 * Initialize indirect rendering dispatch table.
751 * \\author Kevin E. Martin <kevin@precisioninsight.com>
752 * \\author Brian Paul <brian@precisioninsight.com>
753 * \\author Ian Romanick <idr@us.ibm.com>
756 #include "indirect_init.h"
757 #include "indirect.h"
762 * No-op function used to initialize functions that have no GLX protocol
765 static int NoOp(void)
771 * Create and initialize a new GL dispatch table. The table is initialized
772 * with GLX indirect rendering protocol functions.
774 __GLapi * __glXNewIndirectAPI( void )
779 entries = _glapi_get_dispatch_table_size();
780 glAPI = (__GLapi *) Xmalloc(entries * sizeof(void *));
782 /* first, set all entries to point to no-op functions */
785 void **dispatch = (void **) glAPI;
786 for (i = 0; i < entries; i++) {
787 dispatch[i] = (void *) NoOp;
791 /* now, initialize the entries we understand */"""
793 def printRealFooter(self
):
799 def printFunction(self
, f
):
800 if f
.category
!= self
.last_category
:
801 self
.last_category
= f
.category
803 print ' /* %s */' % (self
.last_category
)
806 print ' glAPI->%s = __indirect_gl%s;' % (f
.name
, f
.name
)
809 class PrintGlxProtoInit_h(glX_XML
.GlxProto
):
811 glX_XML
.GlxProto
.__init
__(self
)
812 self
.last_category
= ""
813 self
.license
= license
.bsd_license_template
% ( \
814 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
815 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
816 self
.header_tag
= "_INDIRECT_H_"
818 def printRealHeader(self
):
821 * Prototypes for indirect rendering functions.
823 * \\author Kevin E. Martin <kevin@precisioninsight.com>
824 * \\author Ian Romanick <idr@us.ibm.com>
827 self
.printVisibility( "HIDDEN", "hidden" )
832 #include "glxclient.h"
834 extern HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
835 void * dest, GLboolean reply_is_always_array );
837 extern HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
838 __GLXcontext * gc, unsigned max_dim, GLint width, GLint height,
839 GLint depth, GLenum format, GLenum type, void * dest,
840 GLboolean dimensions_in_reply );
842 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
843 __GLXcontext * gc, GLint sop, GLint cmdlen );
845 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
846 __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen );
850 def printFunction(self
, f
):
851 print 'extern HIDDEN %s __indirect_gl%s(%s);' % (f
.fn_return_type
, f
.name
, f
.get_parameter_string())
855 print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys
.argv
[0]
856 print " -m output_mode Output mode can be one of 'proto', 'init_c' or 'init_h'."
857 print " -d Enable extra debug information in the generated code."
861 if __name__
== '__main__':
862 file_name
= "gl_API.xml"
865 (args
, trail
) = getopt
.getopt(sys
.argv
[1:], "f:m:d")
871 for (arg
,val
) in args
:
880 dh
= PrintGlxProtoStubs()
881 elif mode
== "init_c":
882 dh
= PrintGlxProtoInit_c()
883 elif mode
== "init_h":
884 dh
= PrintGlxProtoInit_h()
888 parser
= make_parser()
889 parser
.setFeature(feature_namespaces
, 0)
890 parser
.setContentHandler(dh
)