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 if f
.output
.p_type
.size
== 0:
455 output_size
= f
.output
.p_type
.size
457 output_str
= f
.output
.name
462 if f
.fn_return_type
!= 'void':
463 return_str
= " retval = (%s)" % (f
.fn_return_type
)
465 return_str
= " (void)"
467 if f
.reply_always_array
:
472 print " %s __glXReadReply(dpy, %s, %s, %s);" % (return_str
, output_size
, output_str
, aa
)
475 # Only emit the extra glFinish call for functions
476 # that don't already require a reply from the server.
477 print ' __indirect_glFinish();'
480 print ' printf( "Exit %%s.\\n", "gl%s" );' % (f
.name
)
483 print ' UnlockDisplay(dpy); SyncHandle();'
485 print ' %s' % f
.return_string()
491 def printPixelFunction(self
, f
):
492 """This function could use some major refactoring. :("""
494 # There is a code-space optimization that we can do here.
495 # Functions that are marked img_pad_dimensions have a version
496 # with an odd number of dimensions and an even number of
497 # dimensions. TexSubImage1D and TexSubImage2D are examples.
498 # We can emit a single function that does both, and have the
499 # real functions call the utility function with the correct
502 # The only quirk to this is that utility funcitons will be
503 # generated for 3D and 4D functions, but 4D (e.g.,
504 # GL_SGIS_texture4D) isn't typically supported. This is
505 # probably not an issue. However, it would be possible to
506 # look at the total set of functions and determine if there
507 # is another function that would actually use the utility
508 # function. If not, then fallback to the normal way of
511 if f
.image
.img_pad_dimensions
:
512 # Determine the hash key and the name for the utility
513 # function that is used to implement the real
516 [h
, n
] = hash_pixel_function(f
)
519 # If the utility function is not yet known, generate
522 if not self
.pixel_stubs
.has_key(h
):
523 self
.pixel_stubs
[h
] = n
524 pixel_func
= glXPixelFunctionUtility(f
, n
)
527 print '%s( unsigned opcode, unsigned dim, %s )' % (n
, pixel_func
.get_parameter_string())
530 if self
.common_func_print_just_start(pixel_func
):
538 if pixel_func
.can_be_large
:
539 print '%s if (cmdlen <= gc->maxSmallRenderCommandSize) {' % (indent
)
540 print '%s if ( (gc->pc + cmdlen) > gc->bufEnd ) {' % (indent
)
541 print '%s (void) __glXFlushRenderBuffer(gc, gc->pc);' % (indent
)
542 print '%s }' % (indent
)
545 [dim
, width
, height
, depth
, extent
] = pixel_func
.dimensions()
546 adjust
= pixel_func
.offset_of_first_parameter() + 4
548 print '%s emit_header(gc->pc, opcode, cmdlen);' % (indent
)
550 offset
= self
.pixel_emit_args(pixel_func
, "gc->pc", indent
, adjust
, dim
, 0)
552 s
= pixel_func
.command_fixed_length()
554 pixHeaderPtr
= "gc->pc + 4"
555 pcPtr
= "gc->pc + %u" % (s
+ 4)
557 if pixel_func
.image
.img_send_null
:
558 condition
= '(compsize > 0) && (%s != NULL)' % (pixel_func
.image
.name
)
560 condition
= 'compsize > 0'
562 print '%s if (%s) {' % (indent
, condition
)
563 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
)
564 print '%s }' % (indent
)
565 print '%s else {' % (indent
)
566 print '%s (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (indent
, pixHeaderPtr
, dim
, dim
)
567 print '%s }' % (indent
)
569 print '%s gc->pc += cmdlen;' % (indent
)
570 print '%s if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent
)
575 print '%s}' % (indent
)
576 print '%selse {' % (indent
)
578 self
.large_emit_begin(indent
, pixel_func
, "opcode")
579 offset
= self
.pixel_emit_args(pixel_func
, "pc", indent
, adjust
, dim
, 1)
581 pixHeaderPtr
= "pc + 8"
582 pcPtr
= "pc + %u" % (s
+ 8)
584 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
)
586 print '%s}' % (indent
)
588 if trailer
: print trailer
594 # Generate the real function as a call to the
597 self
.common_func_print_just_header(f
)
599 [dim
, junk
, junk
, junk
, junk
] = f
.dimensions()
602 for p
in gl_XML
.glFunction
.parameterIterator(f
):
603 p_string
+= ", " + p
.name
608 print ' %s(%s, %u%s );' % (n
, f
.opcode_name(), dim
, p_string
)
614 if self
.common_func_print_header(f
):
623 print '%s if (cmdlen <= gc->maxSmallRenderCommandSize) {' % (indent
)
624 print '%s if ( (gc->pc + cmdlen) > gc->bufEnd ) {' % (indent
)
625 print '%s (void) __glXFlushRenderBuffer(gc, gc->pc);' % (indent
)
626 print '%s }' % (indent
)
629 [dim
, width
, height
, depth
, extent
] = f
.dimensions()
630 adjust
= f
.offset_of_first_parameter() + 4
632 print '%s emit_header(gc->pc, %s, cmdlen);' % (indent
, f
.opcode_real_name())
634 offset
= self
.pixel_emit_args(f
, "gc->pc", indent
, adjust
, dim
, 0)
636 s
= f
.command_fixed_length()
638 pixHeaderPtr
= "gc->pc + 4"
639 pcPtr
= "gc->pc + %u" % (s
+ 4)
641 if f
.image
.img_send_null
:
642 condition
= '(compsize > 0) && (%s != NULL)' % (f
.image
.name
)
644 condition
= 'compsize > 0'
646 print '%s if (%s) {' % (indent
, condition
)
647 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
)
648 print '%s }' % (indent
)
649 print '%s else {' % (indent
)
650 print '%s (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (indent
, pixHeaderPtr
, dim
, dim
)
651 print '%s }' % (indent
)
653 print '%s gc->pc += cmdlen;' % (indent
)
654 print '%s if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent
)
659 print '%s}' % (indent
)
660 print '%selse {' % (indent
)
662 self
.large_emit_begin(indent
, f
)
663 offset
= self
.pixel_emit_args(f
, "pc", indent
, adjust
, dim
, 1)
665 pixHeaderPtr
= "pc + 8"
666 pcPtr
= "pc + %u" % (s
+ 8)
668 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
)
670 print '%s}' % (indent
)
672 if trailer
: print trailer
678 def printRenderFunction(self
, f
):
679 # There is a class of GL functions that take a single pointer
680 # as a parameter. This pointer points to a fixed-size chunk
681 # of data, and the protocol for this functions is very
682 # regular. Since they are so regular and there are so many
683 # of them, special case them with generic functions. On
684 # x86, this saves about 26KB in the libGL.so binary.
686 if f
.variable_length_parameter() == None and len(f
.fn_parameters
) == 1:
687 p
= f
.fn_parameters
[0]
689 cmdlen
= f
.command_fixed_length()
690 if cmdlen
in self
.generic_sizes
:
691 self
.common_func_print_just_header(f
)
692 print ' generic_%u_byte( %s, %s );' % (cmdlen
, f
.opcode_real_name(), p
.name
)
697 if self
.common_func_print_header(f
):
705 print '%s printf( "Enter %%s...\\n", "gl%s" );' % (indent
, f
.name
)
708 print '%s if (cmdlen <= gc->maxSmallRenderCommandSize) {' % (indent
)
709 print '%s if ( (gc->pc + cmdlen) > gc->bufEnd ) {' % (indent
)
710 print '%s (void) __glXFlushRenderBuffer(gc, gc->pc);' % (indent
)
711 print '%s }' % (indent
)
714 print '%s emit_header(gc->pc, %s, cmdlen);' % (indent
, f
.opcode_real_name())
716 self
.common_emit_args(f
, "gc->pc", indent
, 4, 0)
717 print '%s gc->pc += cmdlen;' % (indent
)
718 print '%s if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent
)
721 print '%s}' % (indent
)
722 print '%selse {' % (indent
)
724 self
.large_emit_begin(indent
, f
)
725 offset
= self
.common_emit_args(f
, "pc", indent
, 8, 1)
727 p
= f
.variable_length_parameter()
728 print '%s __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (indent
, offset
+ 8, p
.name
, p
.size_string())
729 print '%s}' % (indent
)
732 print '%s __indirect_glFinish();' % (indent
)
733 print '%s printf( "Exit %%s.\\n", "gl%s" );' % (indent
, f
.name
)
735 if trailer
: print trailer
741 class PrintGlxProtoInit_c(glX_XML
.GlxProto
):
743 glX_XML
.GlxProto
.__init
__(self
)
744 self
.last_category
= ""
745 self
.license
= license
.bsd_license_template
% ( \
746 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
747 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
750 def printRealHeader(self
):
752 * \\file indirect_init.c
753 * Initialize indirect rendering dispatch table.
755 * \\author Kevin E. Martin <kevin@precisioninsight.com>
756 * \\author Brian Paul <brian@precisioninsight.com>
757 * \\author Ian Romanick <idr@us.ibm.com>
760 #include "indirect_init.h"
761 #include "indirect.h"
766 * No-op function used to initialize functions that have no GLX protocol
769 static int NoOp(void)
775 * Create and initialize a new GL dispatch table. The table is initialized
776 * with GLX indirect rendering protocol functions.
778 __GLapi * __glXNewIndirectAPI( void )
783 entries = _glapi_get_dispatch_table_size();
784 glAPI = (__GLapi *) Xmalloc(entries * sizeof(void *));
786 /* first, set all entries to point to no-op functions */
789 void **dispatch = (void **) glAPI;
790 for (i = 0; i < entries; i++) {
791 dispatch[i] = (void *) NoOp;
795 /* now, initialize the entries we understand */"""
797 def printRealFooter(self
):
803 def printFunction(self
, f
):
804 if f
.category
!= self
.last_category
:
805 self
.last_category
= f
.category
807 print ' /* %s */' % (self
.last_category
)
810 print ' glAPI->%s = __indirect_gl%s;' % (f
.name
, f
.name
)
813 class PrintGlxProtoInit_h(glX_XML
.GlxProto
):
815 glX_XML
.GlxProto
.__init
__(self
)
816 self
.last_category
= ""
817 self
.license
= license
.bsd_license_template
% ( \
818 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
819 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
820 self
.header_tag
= "_INDIRECT_H_"
822 def printRealHeader(self
):
825 * Prototypes for indirect rendering functions.
827 * \\author Kevin E. Martin <kevin@precisioninsight.com>
828 * \\author Ian Romanick <idr@us.ibm.com>
831 self
.printVisibility( "HIDDEN", "hidden" )
836 #include "glxclient.h"
838 extern HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
839 void * dest, GLboolean reply_is_always_array );
841 extern HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
842 __GLXcontext * gc, unsigned max_dim, GLint width, GLint height,
843 GLint depth, GLenum format, GLenum type, void * dest,
844 GLboolean dimensions_in_reply );
846 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
847 __GLXcontext * gc, GLint sop, GLint cmdlen );
849 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
850 __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen );
854 def printFunction(self
, f
):
855 print 'extern HIDDEN %s __indirect_gl%s(%s);' % (f
.fn_return_type
, f
.name
, f
.get_parameter_string())
859 print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys
.argv
[0]
860 print " -m output_mode Output mode can be one of 'proto', 'init_c' or 'init_h'."
861 print " -d Enable extra debug information in the generated code."
865 if __name__
== '__main__':
866 file_name
= "gl_API.xml"
869 (args
, trail
) = getopt
.getopt(sys
.argv
[1:], "f:m:d")
875 for (arg
,val
) in args
:
884 dh
= PrintGlxProtoStubs()
885 elif mode
== "init_c":
886 dh
= PrintGlxProtoInit_c()
887 elif mode
== "init_h":
888 dh
= PrintGlxProtoInit_h()
892 parser
= make_parser()
893 parser
.setFeature(feature_namespaces
, 1)
894 parser
.setContentHandler(dh
)