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>
27 # Jeremy Kolb <jkolb@brandeis.edu>
29 import gl_XML
, glX_XML
, glX_proto_common
, license
30 import sys
, getopt
, copy
, string
32 def convertStringForXCB(str):
37 if str[i
:i
+3] in special
:
38 tmp
= '%s_%s' % (tmp
, string
.lower(str[i
:i
+3]))
40 elif str[i
].isupper():
41 tmp
= '%s_%s' % (tmp
, string
.lower(str[i
]))
43 tmp
= '%s%s' % (tmp
, str[i
])
47 def hash_pixel_function(func
):
48 """Generate a 'unique' key for a pixel function. The key is based on
49 the parameters written in the command packet. This includes any
50 padding that might be added for the original function and the 'NULL
57 for param
in func
.parameterIterateGlxSend():
59 [dim
, junk
, junk
, junk
, junk
] = param
.get_dimensions()
62 hash_pre
= "%uD%uD_" % (d
- 1, d
)
64 if param
.img_null_flag
:
67 h
+= "%u" % (param
.size())
69 if func
.pad_after(param
):
73 n
= func
.name
.replace("%uD" % (dim
), "")
74 n
= "__glx_%s_%uD%uD" % (n
, d
- 1, d
)
76 h
= hash_pre
+ h
+ hash_suf
80 class glx_pixel_function_stub(glX_XML
.glx_function
):
81 """Dummy class used to generate pixel "utility" functions that are
82 shared by multiple dimension image functions. For example, these
83 objects are used to generate shared functions used to send GLX
84 protocol for TexImage1D and TexImage2D, TexSubImage1D and
85 TexSubImage2D, etc."""
87 def __init__(self
, func
, name
):
88 # The parameters to the utility function are the same as the
89 # parameters to the real function except for the added "pad"
95 self
.parameters_by_name
= {}
96 for _p
in func
.parameterIterator():
98 self
.parameters
.append(p
)
99 self
.parameters_by_name
[ p
.name
] = p
103 self
.images
.append(p
)
106 if p
.img_yoff
== None:
107 p
.img_yoff
= "yoffset"
113 if p
.img_woff
== None:
114 p
.img_woff
= "woffset"
117 pad_name
= func
.pad_after(p
)
121 self
.parameters
.append(pad
)
122 self
.parameters_by_name
[ pad
.name
] = pad
125 self
.return_type
= func
.return_type
129 self
.glx_vendorpriv
= 0
131 self
.glx_doubles_in_order
= func
.glx_doubles_in_order
133 self
.vectorequiv
= None
135 self
.can_be_large
= func
.can_be_large
136 self
.reply_always_array
= func
.reply_always_array
137 self
.dimensions_in_reply
= func
.dimensions_in_reply
138 self
.img_reset
= None
140 self
.server_handcode
= 0
141 self
.client_handcode
= 0
144 self
.count_parameter_list
= func
.count_parameter_list
145 self
.counter_list
= func
.counter_list
146 self
.offsets_calculated
= 0
150 class PrintGlxProtoStubs(glX_proto_common
.glx_print_proto
):
152 glX_proto_common
.glx_print_proto
.__init
__(self
)
153 self
.name
= "glX_proto_send.py (from Mesa)"
154 self
.license
= license
.bsd_license_template
% ( "(C) Copyright IBM Corporation 2004, 2005", "IBM")
157 self
.last_category
= ""
158 self
.generic_sizes
= [3, 4, 6, 8, 12, 16, 24, 32]
159 self
.pixel_stubs
= {}
163 def printRealHeader(self
):
165 print '#include <GL/gl.h>'
166 print '#include "indirect.h"'
167 print '#include "glxclient.h"'
168 print '#include "indirect_size.h"'
169 print '#include <GL/glxproto.h>'
170 print '#ifdef USE_XCB'
171 print '#include <X11/Xlib-xcb.h>'
172 print '#include <xcb/xcb.h>'
173 print '#include <xcb/glx.h>'
174 print '#endif /* USE_XCB */'
177 print '#define __GLX_PAD(n) (((n) + 3) & ~3)'
182 print '#if !defined __GNUC__ || __GNUC__ < 3'
183 print '# define __builtin_expect(x, y) x'
186 print '/* If the size and opcode values are known at compile-time, this will, on'
187 print ' * x86 at least, emit them with a single instruction.'
189 print '#define emit_header(dest, op, size) \\'
190 print ' do { union { short s[2]; int i; } temp; \\'
191 print ' temp.s[0] = (size); temp.s[1] = (op); \\'
192 print ' *((int *)(dest)) = temp.i; } while(0)'
194 print """NOINLINE CARD32
195 __glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array )
197 xGLXSingleReply reply;
199 (void) _XReply(dpy, (xReply *) & reply, 0, False);
201 if ((reply.length > 0) || reply_is_always_array) {
202 const GLint bytes = (reply_is_always_array)
203 ? (4 * reply.length) : (reply.size * size);
204 const GLint extra = 4 - (bytes & 3);
206 _XRead(dpy, dest, bytes);
208 _XEatData(dpy, extra);
212 (void) memcpy( dest, &(reply.pad3), size);
220 __glXReadPixelReply( Display *dpy, __GLXcontext * gc, unsigned max_dim,
221 GLint width, GLint height, GLint depth, GLenum format, GLenum type,
222 void * dest, GLboolean dimensions_in_reply )
224 xGLXSingleReply reply;
227 (void) _XReply(dpy, (xReply *) & reply, 0, False);
229 if ( dimensions_in_reply ) {
234 if ((height == 0) || (max_dim < 2)) { height = 1; }
235 if ((depth == 0) || (max_dim < 3)) { depth = 1; }
238 size = reply.length * 4;
240 void * buf = Xmalloc( size );
243 _XEatData(dpy, size);
244 __glXSetError(gc, GL_OUT_OF_MEMORY);
247 const GLint extra = 4 - (size & 3);
249 _XRead(dpy, buf, size);
251 _XEatData(dpy, extra);
254 __glEmptyImage(gc, 3, width, height, depth, format, type,
261 #define X_GLXSingle 0
263 NOINLINE FASTCALL GLubyte *
264 __glXSetupSingleRequest( __GLXcontext * gc, GLint sop, GLint cmdlen )
267 Display * const dpy = gc->currentDpy;
269 (void) __glXFlushRenderBuffer(gc, gc->pc);
271 GetReqExtra(GLXSingle, cmdlen, req);
272 req->reqType = gc->majorOpcode;
273 req->contextTag = gc->currentContextTag;
275 return (GLubyte *)(req) + sz_xGLXSingleReq;
278 NOINLINE FASTCALL GLubyte *
279 __glXSetupVendorRequest( __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen )
281 xGLXVendorPrivateReq * req;
282 Display * const dpy = gc->currentDpy;
284 (void) __glXFlushRenderBuffer(gc, gc->pc);
286 GetReqExtra(GLXVendorPrivate, cmdlen, req);
287 req->reqType = gc->majorOpcode;
289 req->vendorCode = vop;
290 req->contextTag = gc->currentContextTag;
291 return (GLubyte *)(req) + sz_xGLXVendorPrivateReq;
294 const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 };
296 #define zero (__glXDefaultPixelStore+0)
297 #define one (__glXDefaultPixelStore+8)
298 #define default_pixel_store_1D (__glXDefaultPixelStore+4)
299 #define default_pixel_store_1D_size 20
300 #define default_pixel_store_2D (__glXDefaultPixelStore+4)
301 #define default_pixel_store_2D_size 20
302 #define default_pixel_store_3D (__glXDefaultPixelStore+0)
303 #define default_pixel_store_3D_size 36
304 #define default_pixel_store_4D (__glXDefaultPixelStore+0)
305 #define default_pixel_store_4D_size 36
308 for size
in self
.generic_sizes
:
309 self
.print_generic_function(size
)
313 def printBody(self
, api
):
315 self
.pixel_stubs
= {}
318 for func
in api
.functionIterateGlx():
319 if func
.client_handcode
: continue
321 # If the function is a pixel function with a certain
322 # GLX protocol signature, create a fake stub function
323 # for it. For example, create a single stub function
324 # that is used to implement both glTexImage1D and
327 if func
.glx_rop
!= 0:
329 for image
in func
.get_images():
330 if image
.img_pad_dimensions
:
336 [h
, n
] = hash_pixel_function(func
)
339 self
.pixel_stubs
[ func
.name
] = n
340 if h
not in generated_stubs
:
341 generated_stubs
.append(h
)
343 fake_func
= glx_pixel_function_stub( func
, n
)
344 self
.printFunction( fake_func
)
347 self
.printFunction( func
)
352 def printFunction(self
, func
):
353 if func
.glx_rop
== ~
0:
354 print 'static %s' % (func
.return_type
)
355 print '%s( unsigned opcode, unsigned dim, %s )' % (func
.name
, func
.get_parameter_string())
357 print '#define %s %d' % (func
.opcode_name(), func
.opcode_value())
359 print '%s' % (func
.return_type
)
360 print '__indirect_gl%s(%s)' % (func
.name
, func
.get_parameter_string())
366 if func
.glx_rop
!= 0 or func
.vectorequiv
!= None:
368 self
.printPixelFunction(func
)
370 self
.printRenderFunction(func
)
371 elif func
.glx_sop
!= 0 or func
.glx_vendorpriv
!= 0:
372 self
.printSingleFunction(func
)
375 print "/* Missing GLX protocol for %s. */" % (func
.name
)
383 def print_generic_function(self
, n
):
385 print """static FASTCALL NOINLINE void
386 generic_%u_byte( GLint rop, const void * ptr )
388 __GLXcontext * const gc = __glXGetCurrentContext();
389 const GLuint cmdlen = %u;
391 emit_header(gc->pc, rop, cmdlen);
392 (void) memcpy((void *)(gc->pc + 4), ptr, %u);
394 if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }
396 """ % (n
, size
+ 4, size
)
400 def common_emit_one_arg(self
, p
, pc
, adjust
, extra_offset
):
404 src_ptr
= "&" + p
.name
407 print '(void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
408 % (pc
, p
.offset
+ adjust
, src_ptr
, p
.size_string() )
410 print '(void) memcpy((void *)(%s + %u + %s), (void *)(%s), %s);' \
411 % (pc
, p
.offset
+ adjust
, extra_offset
, src_ptr
, p
.size_string() )
413 def common_emit_args(self
, f
, pc
, adjust
, skip_vla
):
416 for p
in f
.parameterIterateGlxSend( not skip_vla
):
417 if p
.name
!= f
.img_reset
:
418 self
.common_emit_one_arg(p
, pc
, adjust
, extra_offset
)
420 if p
.is_variable_length():
421 temp
= p
.size_string()
423 extra_offset
+= " + %s" % (temp
)
430 def pixel_emit_args(self
, f
, pc
, large
):
431 """Emit the arguments for a pixel function. This differs from
432 common_emit_args in that pixel functions may require padding
433 be inserted (i.e., for the missing width field for
434 TexImage1D), and they may also require a 'NULL image' flag
435 be inserted before the image data."""
442 for param
in f
.parameterIterateGlxSend():
443 if not param
.is_image():
444 self
.common_emit_one_arg(param
, pc
, adjust
, None)
446 if f
.pad_after(param
):
447 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
+ param
.size()) + adjust
)
450 [dim
, width
, height
, depth
, extent
] = param
.get_dimensions()
456 if param
.img_null_flag
:
458 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
- 4) + adjust
)
460 print '(void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (pc
, (param
.offset
- 4) + adjust
, param
.name
)
463 pixHeaderPtr
= "%s + %u" % (pc
, adjust
)
464 pcPtr
= "%s + %u" % (pc
, param
.offset
+ adjust
)
467 if param
.img_send_null
:
468 condition
= '(compsize > 0) && (%s != NULL)' % (param
.name
)
470 condition
= 'compsize > 0'
472 print 'if (%s) {' % (condition
)
473 print ' (*gc->fillImage)(gc, %s, %s, %s, %s, %s, %s, %s, %s, %s);' % (dim_str
, width
, height
, depth
, param
.img_format
, param
.img_type
, param
.name
, pcPtr
, pixHeaderPtr
)
475 print ' (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (pixHeaderPtr
, dim
, dim
)
478 print '__glXSendLargeImage(gc, compsize, %s, %s, %s, %s, %s, %s, %s, %s, %s);' % (dim_str
, width
, height
, depth
, param
.img_format
, param
.img_type
, param
.name
, pcPtr
, pixHeaderPtr
)
483 def large_emit_begin(self
, f
, op_name
= None):
485 op_name
= f
.opcode_real_name()
487 print 'const GLint op = %s;' % (op_name
)
488 print 'const GLuint cmdlenLarge = cmdlen + 4;'
489 print 'GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);'
490 print '(void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);'
491 print '(void) memcpy((void *)(pc + 4), (void *)(&op), 4);'
495 def common_func_print_just_start(self
, f
):
496 print ' __GLXcontext * const gc = __glXGetCurrentContext();'
498 # The only reason that single and vendor private commands need
499 # a variable called 'dpy' is becuase they use the SyncHandle
500 # macro. For whatever brain-dead reason, that macro is hard-
501 # coded to use a variable called 'dpy' instead of taking a
504 # FIXME Simplify the logic related to skip_condition and
505 # FIXME condition_list in this function. Basically, remove
506 # FIXME skip_condition, and just append the "dpy != NULL" type
507 # FIXME condition to condition_list from the start. The only
508 # FIXME reason it's done in this confusing way now is to
509 # FIXME minimize the diffs in the generated code.
512 for p
in f
.parameterIterateOutputs():
514 print ' const __GLXattribute * const state = gc->client_state_private;'
517 print ' Display * const dpy = gc->currentDpy;'
518 skip_condition
= "dpy != NULL"
520 skip_condition
= "gc->currentDpy != NULL"
522 skip_condition
= None
525 if f
.return_type
!= 'void':
526 print ' %s retval = (%s) 0;' % (f
.return_type
, f
.return_type
)
529 self
.emit_packet_size_calculation(f
, 0)
532 for p
in f
.parameterIterateCounters():
533 condition_list
.append( "%s >= 0" % (p
.name
) )
536 condition_list
.append( skip_condition
)
538 if len( condition_list
) > 0:
539 if len( condition_list
) > 1:
540 skip_condition
= "(%s)" % (string
.join( condition_list
, ") && (" ))
542 skip_condition
= "%s" % (condition_list
.pop(0))
544 print ' if (__builtin_expect(%s, 1)) {' % (skip_condition
)
550 def printSingleFunction(self
, f
):
551 self
.common_func_print_just_start(f
)
554 print ' printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
556 if f
.glx_vendorpriv
== 0:
559 print '#ifdef USE_XCB'
561 print ' printf("\\tUsing XCB.\\n");'
562 print ' xcb_connection_t *c = XGetXCBConnection(dpy);'
563 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
564 xcb_name
= 'xcb_glx%s' % convertStringForXCB(f
.name
)
569 for p
in f
.parameterIterator():
574 if p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP":
575 extra_iparams
.append("state->storePack.swapEndian")
577 extra_iparams
.append("0")
579 # Hardcode this in. lsb_first param (apparently always GL_FALSE)
580 # also present in GetPolygonStipple, but taken care of above.
581 if xcb_name
== "xcb_glx_read_pixels":
582 extra_iparams
.append("0")
584 iparams
.append(p
.name
)
587 xcb_request
= '%s(%s)' % (xcb_name
, ", ".join(["c", "gc->currentContextTag"] + iparams
+ extra_iparams
))
590 print ' %s_reply_t *reply = %s_reply(c, %s, NULL);' % (xcb_name
, xcb_name
, xcb_request
)
591 if output
and f
.reply_always_array
:
592 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
594 elif output
and not f
.reply_always_array
:
595 if not output
.is_image():
596 print ' if (%s_data_length(reply) == 0)' % (xcb_name
)
597 print ' (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output
.name
)
599 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
602 if f
.return_type
!= 'void':
603 print ' retval = reply->ret_val;'
604 print ' free(reply);'
606 print ' ' + xcb_request
+ ';'
608 # End of XCB specific.
611 if f
.parameters
!= []:
612 pc_decl
= "GLubyte const * pc ="
616 if f
.glx_vendorpriv
!= 0:
617 print ' %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl
, f
.opcode_real_name(), f
.opcode_name())
619 print ' %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl
, f
.opcode_name())
621 self
.common_emit_args(f
, "pc", 0, 0)
623 images
= f
.get_images()
627 o
= f
.command_fixed_length() - 4
628 print ' *(int32_t *)(pc + %u) = 0;' % (o
)
629 if img
.img_format
!= "GL_COLOR_INDEX" or img
.img_type
!= "GL_BITMAP":
630 print ' * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o
)
633 print ' * (int8_t *)(pc + %u) = %s;' % (o
+ 1, f
.img_reset
)
638 if f
.return_type
!= 'void':
639 return_name
= " retval"
640 return_str
= " retval = (%s)" % (f
.return_type
)
642 return_str
= " (void)"
646 for p
in f
.parameterIterateOutputs():
648 [dim
, w
, h
, d
, junk
] = p
.get_dimensions()
649 if f
.dimensions_in_reply
:
650 print " __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim
, p
.img_format
, p
.img_type
, p
.name
)
652 print " __glXReadPixelReply(dpy, gc, %u, %s, %s, %s, %s, %s, %s, GL_FALSE);" % (dim
, w
, h
, d
, p
.img_format
, p
.img_type
, p
.name
)
656 if f
.reply_always_array
:
661 # gl_parameter.size() returns the size
662 # of the entire data item. If the
663 # item is a fixed-size array, this is
664 # the size of the whole array. This
665 # is not what __glXReadReply wants. It
666 # wants the size of a single data
667 # element in the reply packet.
668 # Dividing by the array size (1 for
669 # non-arrays) gives us this.
671 s
= p
.size() / p
.get_element_count()
672 print " %s __glXReadReply(dpy, %s, %s, %s);" % (return_str
, s
, p
.name
, aa
)
676 # If a reply wasn't read to fill an output parameter,
677 # read a NULL reply to get the return value.
680 print " %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str
)
684 # Only emit the extra glFinish call for functions
685 # that don't already require a reply from the server.
686 print ' __indirect_glFinish();'
689 print ' printf( "Exit %%s.\\n", "gl%s" );' % (f
.name
)
692 print ' UnlockDisplay(dpy); SyncHandle();'
694 if f
.glx_vendorpriv
== 0:
695 print '#endif /* USE_XCB */'
698 print ' return%s;' % (return_name
)
702 def printPixelFunction(self
, f
):
703 if self
.pixel_stubs
.has_key( f
.name
):
704 # Normally gl_function::get_parameter_string could be
705 # used. However, this call needs to have the missing
706 # dimensions (e.g., a fake height value for
707 # glTexImage1D) added in.
710 for param
in f
.parameterIterateGlxSend():
711 p_string
+= ", " + param
.name
714 [dim
, junk
, junk
, junk
, junk
] = param
.get_dimensions()
716 if f
.pad_after(param
):
719 print ' %s(%s, %u%s );' % (self
.pixel_stubs
[f
.name
] , f
.opcode_name(), dim
, p_string
)
723 if self
.common_func_print_just_start(f
):
730 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
731 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
732 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
738 opcode
= f
.opcode_real_name()
740 print 'emit_header(gc->pc, %s, cmdlen);' % (opcode
)
742 self
.pixel_emit_args( f
, "gc->pc", 0 )
743 print 'gc->pc += cmdlen;'
744 print 'if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
750 self
.large_emit_begin(f
, opcode
)
751 self
.pixel_emit_args(f
, "pc", 1)
755 if trailer
: print trailer
759 def printRenderFunction(self
, f
):
760 # There is a class of GL functions that take a single pointer
761 # as a parameter. This pointer points to a fixed-size chunk
762 # of data, and the protocol for this functions is very
763 # regular. Since they are so regular and there are so many
764 # of them, special case them with generic functions. On
765 # x86, this saves about 26KB in the libGL.so binary.
767 if f
.variable_length_parameter() == None and len(f
.parameters
) == 1:
770 cmdlen
= f
.command_fixed_length()
771 if cmdlen
in self
.generic_sizes
:
772 print ' generic_%u_byte( %s, %s );' % (cmdlen
, f
.opcode_real_name(), p
.name
)
775 if self
.common_func_print_just_start(f
):
781 print 'printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
784 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
785 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
786 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
789 print 'emit_header(gc->pc, %s, cmdlen);' % (f
.opcode_real_name())
791 self
.common_emit_args(f
, "gc->pc", 4, 0)
792 print 'gc->pc += cmdlen;'
793 print 'if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
799 self
.large_emit_begin(f
)
800 self
.common_emit_args(f
, "pc", 8, 1)
802 p
= f
.variable_length_parameter()
803 print ' __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (p
.offset
+ 8, p
.name
, p
.size_string())
807 print '__indirect_glFinish();'
808 print 'printf( "Exit %%s.\\n", "gl%s" );' % (f
.name
)
810 if trailer
: print trailer
814 class PrintGlxProtoInit_c(gl_XML
.gl_print_base
):
816 gl_XML
.gl_print_base
.__init
__(self
)
818 self
.name
= "glX_proto_send.py (from Mesa)"
819 self
.license
= license
.bsd_license_template
% ( \
820 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
821 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
825 def printRealHeader(self
):
827 * \\file indirect_init.c
828 * Initialize indirect rendering dispatch table.
830 * \\author Kevin E. Martin <kevin@precisioninsight.com>
831 * \\author Brian Paul <brian@precisioninsight.com>
832 * \\author Ian Romanick <idr@us.ibm.com>
835 #include "indirect_init.h"
836 #include "indirect.h"
841 * No-op function used to initialize functions that have no GLX protocol
844 static int NoOp(void)
850 * Create and initialize a new GL dispatch table. The table is initialized
851 * with GLX indirect rendering protocol functions.
853 __GLapi * __glXNewIndirectAPI( void )
858 entries = _glapi_get_dispatch_table_size();
859 glAPI = (__GLapi *) Xmalloc(entries * sizeof(void *));
861 /* first, set all entries to point to no-op functions */
864 void **dispatch = (void **) glAPI;
865 for (i = 0; i < entries; i++) {
866 dispatch[i] = (void *) NoOp;
870 /* now, initialize the entries we understand */"""
872 def printRealFooter(self
):
880 def printBody(self
, api
):
881 for [name
, number
] in api
.categoryIterate():
883 preamble
= '\n /* %3u. %s */\n\n' % (int(number
), name
)
885 preamble
= '\n /* %s */\n\n' % (name
)
887 for func
in api
.functionIterateByCategory(name
):
888 if func
.client_supported_for_indirect():
889 print '%s glAPI->%s = __indirect_gl%s;' % (preamble
, func
.name
, func
.name
)
895 class PrintGlxProtoInit_h(gl_XML
.gl_print_base
):
897 gl_XML
.gl_print_base
.__init
__(self
)
899 self
.name
= "glX_proto_send.py (from Mesa)"
900 self
.license
= license
.bsd_license_template
% ( \
901 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
902 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
903 self
.header_tag
= "_INDIRECT_H_"
905 self
.last_category
= ""
909 def printRealHeader(self
):
912 * Prototypes for indirect rendering functions.
914 * \\author Kevin E. Martin <kevin@precisioninsight.com>
915 * \\author Ian Romanick <idr@us.ibm.com>
918 self
.printVisibility( "HIDDEN", "hidden" )
923 #include "glxclient.h"
925 extern HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
926 void * dest, GLboolean reply_is_always_array );
928 extern HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
929 __GLXcontext * gc, unsigned max_dim, GLint width, GLint height,
930 GLint depth, GLenum format, GLenum type, void * dest,
931 GLboolean dimensions_in_reply );
933 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
934 __GLXcontext * gc, GLint sop, GLint cmdlen );
936 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
937 __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen );
941 def printBody(self
, api
):
942 for func
in api
.functionIterateGlx():
943 print 'extern HIDDEN %s __indirect_gl%s(%s);' % (func
.return_type
, func
.name
, func
.get_parameter_string())
947 print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys
.argv
[0]
948 print " -m output_mode Output mode can be one of 'proto', 'init_c' or 'init_h'."
949 print " -d Enable extra debug information in the generated code."
953 if __name__
== '__main__':
954 file_name
= "gl_API.xml"
957 (args
, trail
) = getopt
.getopt(sys
.argv
[1:], "f:m:d")
963 for (arg
,val
) in args
:
972 printer
= PrintGlxProtoStubs()
973 elif mode
== "init_c":
974 printer
= PrintGlxProtoInit_c()
975 elif mode
== "init_h":
976 printer
= PrintGlxProtoInit_h()
981 printer
.debug
= debug
982 api
= gl_XML
.parse_GL_API( file_name
, glX_XML
.glx_item_factory() )