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 "dispatch.h"'
170 print '#include "glapi.h"'
171 print '#include "glthread.h"'
172 print '#include <GL/glxproto.h>'
173 print '#ifdef USE_XCB'
174 print '#include <X11/Xlib-xcb.h>'
175 print '#include <xcb/xcb.h>'
176 print '#include <xcb/glx.h>'
177 print '#endif /* USE_XCB */'
180 print '#define __GLX_PAD(n) (((n) + 3) & ~3)'
185 print '#if !defined __GNUC__ || __GNUC__ < 3'
186 print '# define __builtin_expect(x, y) x'
189 print '/* If the size and opcode values are known at compile-time, this will, on'
190 print ' * x86 at least, emit them with a single instruction.'
192 print '#define emit_header(dest, op, size) \\'
193 print ' do { union { short s[2]; int i; } temp; \\'
194 print ' temp.s[0] = (size); temp.s[1] = (op); \\'
195 print ' *((int *)(dest)) = temp.i; } while(0)'
197 print """NOINLINE CARD32
198 __glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array )
200 xGLXSingleReply reply;
202 (void) _XReply(dpy, (xReply *) & reply, 0, False);
204 if ((reply.length > 0) || reply_is_always_array) {
205 const GLint bytes = (reply_is_always_array)
206 ? (4 * reply.length) : (reply.size * size);
207 const GLint extra = 4 - (bytes & 3);
209 _XRead(dpy, dest, bytes);
211 _XEatData(dpy, extra);
215 (void) memcpy( dest, &(reply.pad3), size);
223 __glXReadPixelReply( Display *dpy, __GLXcontext * gc, unsigned max_dim,
224 GLint width, GLint height, GLint depth, GLenum format, GLenum type,
225 void * dest, GLboolean dimensions_in_reply )
227 xGLXSingleReply reply;
230 (void) _XReply(dpy, (xReply *) & reply, 0, False);
232 if ( dimensions_in_reply ) {
237 if ((height == 0) || (max_dim < 2)) { height = 1; }
238 if ((depth == 0) || (max_dim < 3)) { depth = 1; }
241 size = reply.length * 4;
243 void * buf = Xmalloc( size );
246 _XEatData(dpy, size);
247 __glXSetError(gc, GL_OUT_OF_MEMORY);
250 const GLint extra = 4 - (size & 3);
252 _XRead(dpy, buf, size);
254 _XEatData(dpy, extra);
257 __glEmptyImage(gc, 3, width, height, depth, format, type,
264 #define X_GLXSingle 0
266 NOINLINE FASTCALL GLubyte *
267 __glXSetupSingleRequest( __GLXcontext * gc, GLint sop, GLint cmdlen )
270 Display * const dpy = gc->currentDpy;
272 (void) __glXFlushRenderBuffer(gc, gc->pc);
274 GetReqExtra(GLXSingle, cmdlen, req);
275 req->reqType = gc->majorOpcode;
276 req->contextTag = gc->currentContextTag;
278 return (GLubyte *)(req) + sz_xGLXSingleReq;
281 NOINLINE FASTCALL GLubyte *
282 __glXSetupVendorRequest( __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen )
284 xGLXVendorPrivateReq * req;
285 Display * const dpy = gc->currentDpy;
287 (void) __glXFlushRenderBuffer(gc, gc->pc);
289 GetReqExtra(GLXVendorPrivate, cmdlen, req);
290 req->reqType = gc->majorOpcode;
292 req->vendorCode = vop;
293 req->contextTag = gc->currentContextTag;
294 return (GLubyte *)(req) + sz_xGLXVendorPrivateReq;
297 const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 };
299 #define zero (__glXDefaultPixelStore+0)
300 #define one (__glXDefaultPixelStore+8)
301 #define default_pixel_store_1D (__glXDefaultPixelStore+4)
302 #define default_pixel_store_1D_size 20
303 #define default_pixel_store_2D (__glXDefaultPixelStore+4)
304 #define default_pixel_store_2D_size 20
305 #define default_pixel_store_3D (__glXDefaultPixelStore+0)
306 #define default_pixel_store_3D_size 36
307 #define default_pixel_store_4D (__glXDefaultPixelStore+0)
308 #define default_pixel_store_4D_size 36
311 for size
in self
.generic_sizes
:
312 self
.print_generic_function(size
)
316 def printBody(self
, api
):
318 self
.pixel_stubs
= {}
321 for func
in api
.functionIterateGlx():
322 if func
.client_handcode
: continue
324 # If the function is a pixel function with a certain
325 # GLX protocol signature, create a fake stub function
326 # for it. For example, create a single stub function
327 # that is used to implement both glTexImage1D and
330 if func
.glx_rop
!= 0:
332 for image
in func
.get_images():
333 if image
.img_pad_dimensions
:
339 [h
, n
] = hash_pixel_function(func
)
342 self
.pixel_stubs
[ func
.name
] = n
343 if h
not in generated_stubs
:
344 generated_stubs
.append(h
)
346 fake_func
= glx_pixel_function_stub( func
, n
)
347 self
.printFunction(fake_func
, fake_func
.name
)
350 self
.printFunction(func
, func
.name
)
351 if func
.glx_sop
and func
.glx_vendorpriv
:
352 self
.printFunction(func
, func
.glx_vendorpriv_names
[0])
357 def printFunction(self
, func
, name
):
359 if func
.glx_rop
== ~
0:
360 print 'static %s' % (func
.return_type
)
361 print '%s( unsigned opcode, unsigned dim, %s )' % (func
.name
, func
.get_parameter_string())
364 if func
.has_different_protocol(name
):
365 if func
.return_type
== "void":
368 ret_string
= "return "
370 func_name
= func
.static_glx_name(name
)
371 print '#define %s %d' % (func
.opcode_vendor_name(name
), func
.glx_vendorpriv
)
372 print '%s gl%s(%s)' % (func
.return_type
, func_name
, func
.get_parameter_string())
374 print ' __GLXcontext * const gc = __glXGetCurrentContext();'
376 print ' if (gc->driContext) {'
377 print ' %sCALL_%s(GET_DISPATCH(), (%s));' % (ret_string
, func
.name
, func
.get_called_parameter_string())
381 print '#define %s %d' % (func
.opcode_name(), func
.opcode_value())
383 print '%s __indirect_gl%s(%s)' % (func
.return_type
, name
, func
.get_parameter_string())
387 if func
.glx_rop
!= 0 or func
.vectorequiv
!= None:
389 self
.printPixelFunction(func
)
391 self
.printRenderFunction(func
)
392 elif func
.glx_sop
!= 0 or func
.glx_vendorpriv
!= 0:
393 self
.printSingleFunction(func
, name
)
396 print "/* Missing GLX protocol for %s. */" % (name
)
402 def print_generic_function(self
, n
):
404 print """static FASTCALL NOINLINE void
405 generic_%u_byte( GLint rop, const void * ptr )
407 __GLXcontext * const gc = __glXGetCurrentContext();
408 const GLuint cmdlen = %u;
410 emit_header(gc->pc, rop, cmdlen);
411 (void) memcpy((void *)(gc->pc + 4), ptr, %u);
413 if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }
415 """ % (n
, size
+ 4, size
)
419 def common_emit_one_arg(self
, p
, pc
, adjust
, extra_offset
):
423 src_ptr
= "&" + p
.name
426 print '(void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
427 % (pc
, p
.offset
+ adjust
, src_ptr
, p
.size_string() )
429 print '(void) memcpy((void *)(%s + %u + %s), (void *)(%s), %s);' \
430 % (pc
, p
.offset
+ adjust
, extra_offset
, src_ptr
, p
.size_string() )
432 def common_emit_args(self
, f
, pc
, adjust
, skip_vla
):
435 for p
in f
.parameterIterateGlxSend( not skip_vla
):
436 if p
.name
!= f
.img_reset
:
437 self
.common_emit_one_arg(p
, pc
, adjust
, extra_offset
)
439 if p
.is_variable_length():
440 temp
= p
.size_string()
442 extra_offset
+= " + %s" % (temp
)
449 def pixel_emit_args(self
, f
, pc
, large
):
450 """Emit the arguments for a pixel function. This differs from
451 common_emit_args in that pixel functions may require padding
452 be inserted (i.e., for the missing width field for
453 TexImage1D), and they may also require a 'NULL image' flag
454 be inserted before the image data."""
461 for param
in f
.parameterIterateGlxSend():
462 if not param
.is_image():
463 self
.common_emit_one_arg(param
, pc
, adjust
, None)
465 if f
.pad_after(param
):
466 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
+ param
.size()) + adjust
)
469 [dim
, width
, height
, depth
, extent
] = param
.get_dimensions()
475 if param
.img_null_flag
:
477 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
- 4) + adjust
)
479 print '(void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (pc
, (param
.offset
- 4) + adjust
, param
.name
)
482 pixHeaderPtr
= "%s + %u" % (pc
, adjust
)
483 pcPtr
= "%s + %u" % (pc
, param
.offset
+ adjust
)
486 if param
.img_send_null
:
487 condition
= '(compsize > 0) && (%s != NULL)' % (param
.name
)
489 condition
= 'compsize > 0'
491 print 'if (%s) {' % (condition
)
492 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
)
494 print ' (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (pixHeaderPtr
, dim
, dim
)
497 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
)
502 def large_emit_begin(self
, f
, op_name
= None):
504 op_name
= f
.opcode_real_name()
506 print 'const GLint op = %s;' % (op_name
)
507 print 'const GLuint cmdlenLarge = cmdlen + 4;'
508 print 'GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);'
509 print '(void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);'
510 print '(void) memcpy((void *)(pc + 4), (void *)(&op), 4);'
514 def common_func_print_just_start(self
, f
, name
):
515 print ' __GLXcontext * const gc = __glXGetCurrentContext();'
517 # The only reason that single and vendor private commands need
518 # a variable called 'dpy' is becuase they use the SyncHandle
519 # macro. For whatever brain-dead reason, that macro is hard-
520 # coded to use a variable called 'dpy' instead of taking a
523 # FIXME Simplify the logic related to skip_condition and
524 # FIXME condition_list in this function. Basically, remove
525 # FIXME skip_condition, and just append the "dpy != NULL" type
526 # FIXME condition to condition_list from the start. The only
527 # FIXME reason it's done in this confusing way now is to
528 # FIXME minimize the diffs in the generated code.
531 for p
in f
.parameterIterateOutputs():
532 if p
.is_image() and (p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP"):
533 print ' const __GLXattribute * const state = gc->client_state_private;'
536 print ' Display * const dpy = gc->currentDpy;'
537 skip_condition
= "dpy != NULL"
539 skip_condition
= "gc->currentDpy != NULL"
541 skip_condition
= None
544 if f
.return_type
!= 'void':
545 print ' %s retval = (%s) 0;' % (f
.return_type
, f
.return_type
)
548 if name
!= None and name
not in f
.glx_vendorpriv_names
:
549 print '#ifndef USE_XCB'
550 self
.emit_packet_size_calculation(f
, 0)
551 if name
!= None and name
not in f
.glx_vendorpriv_names
:
555 for p
in f
.parameterIterateCounters():
556 condition_list
.append( "%s >= 0" % (p
.name
) )
557 # 'counter' parameters cannot be negative
558 print " if (%s < 0) {" % p
.name
559 print " __glXSetError(gc, GL_INVALID_VALUE);"
560 if f
.return_type
!= 'void':
567 condition_list
.append( skip_condition
)
569 if len( condition_list
) > 0:
570 if len( condition_list
) > 1:
571 skip_condition
= "(%s)" % (string
.join( condition_list
, ") && (" ))
573 skip_condition
= "%s" % (condition_list
.pop(0))
575 print ' if (__builtin_expect(%s, 1)) {' % (skip_condition
)
581 def printSingleFunction(self
, f
, name
):
582 self
.common_func_print_just_start(f
, name
)
585 print ' printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
587 if name
not in f
.glx_vendorpriv_names
:
590 print '#ifdef USE_XCB'
592 print ' printf("\\tUsing XCB.\\n");'
593 print ' xcb_connection_t *c = XGetXCBConnection(dpy);'
594 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
595 xcb_name
= 'xcb_glx%s' % convertStringForXCB(name
)
600 for p
in f
.parameterIterator():
605 if p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP":
606 extra_iparams
.append("state->storePack.swapEndian")
608 extra_iparams
.append("0")
610 # Hardcode this in. lsb_first param (apparently always GL_FALSE)
611 # also present in GetPolygonStipple, but taken care of above.
612 if xcb_name
== "xcb_glx_read_pixels":
613 extra_iparams
.append("0")
615 iparams
.append(p
.name
)
618 xcb_request
= '%s(%s)' % (xcb_name
, ", ".join(["c", "gc->currentContextTag"] + iparams
+ extra_iparams
))
621 print ' %s_reply_t *reply = %s_reply(c, %s, NULL);' % (xcb_name
, xcb_name
, xcb_request
)
622 if output
and f
.reply_always_array
:
623 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
625 elif output
and not f
.reply_always_array
:
626 if not output
.is_image():
627 print ' if (%s_data_length(reply) == 0)' % (xcb_name
)
628 print ' (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output
.name
)
630 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
633 if f
.return_type
!= 'void':
634 print ' retval = reply->ret_val;'
635 print ' free(reply);'
637 print ' ' + xcb_request
+ ';'
639 # End of XCB specific.
642 if f
.parameters
!= []:
643 pc_decl
= "GLubyte const * pc ="
647 if name
in f
.glx_vendorpriv_names
:
648 print ' %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl
, f
.opcode_real_name(), f
.opcode_vendor_name(name
))
650 print ' %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl
, f
.opcode_name())
652 self
.common_emit_args(f
, "pc", 0, 0)
654 images
= f
.get_images()
658 o
= f
.command_fixed_length() - 4
659 print ' *(int32_t *)(pc + %u) = 0;' % (o
)
660 if img
.img_format
!= "GL_COLOR_INDEX" or img
.img_type
!= "GL_BITMAP":
661 print ' * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o
)
664 print ' * (int8_t *)(pc + %u) = %s;' % (o
+ 1, f
.img_reset
)
669 if f
.return_type
!= 'void':
670 return_name
= " retval"
671 return_str
= " retval = (%s)" % (f
.return_type
)
673 return_str
= " (void)"
677 for p
in f
.parameterIterateOutputs():
679 [dim
, w
, h
, d
, junk
] = p
.get_dimensions()
680 if f
.dimensions_in_reply
:
681 print " __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim
, p
.img_format
, p
.img_type
, p
.name
)
683 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
)
687 if f
.reply_always_array
:
692 # gl_parameter.size() returns the size
693 # of the entire data item. If the
694 # item is a fixed-size array, this is
695 # the size of the whole array. This
696 # is not what __glXReadReply wants. It
697 # wants the size of a single data
698 # element in the reply packet.
699 # Dividing by the array size (1 for
700 # non-arrays) gives us this.
702 s
= p
.size() / p
.get_element_count()
703 print " %s __glXReadReply(dpy, %s, %s, %s);" % (return_str
, s
, p
.name
, aa
)
707 # If a reply wasn't read to fill an output parameter,
708 # read a NULL reply to get the return value.
711 print " %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str
)
715 # Only emit the extra glFinish call for functions
716 # that don't already require a reply from the server.
717 print ' __indirect_glFinish();'
720 print ' printf( "Exit %%s.\\n", "gl%s" );' % (name
)
723 print ' UnlockDisplay(dpy); SyncHandle();'
725 if name
not in f
.glx_vendorpriv_names
:
726 print '#endif /* USE_XCB */'
729 print ' return%s;' % (return_name
)
733 def printPixelFunction(self
, f
):
734 if self
.pixel_stubs
.has_key( f
.name
):
735 # Normally gl_function::get_parameter_string could be
736 # used. However, this call needs to have the missing
737 # dimensions (e.g., a fake height value for
738 # glTexImage1D) added in.
741 for param
in f
.parameterIterateGlxSend():
742 p_string
+= ", " + param
.name
745 [dim
, junk
, junk
, junk
, junk
] = param
.get_dimensions()
747 if f
.pad_after(param
):
750 print ' %s(%s, %u%s );' % (self
.pixel_stubs
[f
.name
] , f
.opcode_name(), dim
, p_string
)
754 if self
.common_func_print_just_start(f
, None):
761 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
762 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
763 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
769 opcode
= f
.opcode_real_name()
771 print 'emit_header(gc->pc, %s, cmdlen);' % (opcode
)
773 self
.pixel_emit_args( f
, "gc->pc", 0 )
774 print 'gc->pc += cmdlen;'
775 print 'if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
781 self
.large_emit_begin(f
, opcode
)
782 self
.pixel_emit_args(f
, "pc", 1)
786 if trailer
: print trailer
790 def printRenderFunction(self
, f
):
791 # There is a class of GL functions that take a single pointer
792 # as a parameter. This pointer points to a fixed-size chunk
793 # of data, and the protocol for this functions is very
794 # regular. Since they are so regular and there are so many
795 # of them, special case them with generic functions. On
796 # x86, this saves about 26KB in the libGL.so binary.
798 if f
.variable_length_parameter() == None and len(f
.parameters
) == 1:
801 cmdlen
= f
.command_fixed_length()
802 if cmdlen
in self
.generic_sizes
:
803 print ' generic_%u_byte( %s, %s );' % (cmdlen
, f
.opcode_real_name(), p
.name
)
806 if self
.common_func_print_just_start(f
, None):
812 print 'printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
815 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
816 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
817 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
820 print 'emit_header(gc->pc, %s, cmdlen);' % (f
.opcode_real_name())
822 self
.common_emit_args(f
, "gc->pc", 4, 0)
823 print 'gc->pc += cmdlen;'
824 print 'if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
830 self
.large_emit_begin(f
)
831 self
.common_emit_args(f
, "pc", 8, 1)
833 p
= f
.variable_length_parameter()
834 print ' __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (p
.offset
+ 8, p
.name
, p
.size_string())
838 print '__indirect_glFinish();'
839 print 'printf( "Exit %%s.\\n", "gl%s" );' % (f
.name
)
841 if trailer
: print trailer
845 class PrintGlxProtoInit_c(gl_XML
.gl_print_base
):
847 gl_XML
.gl_print_base
.__init
__(self
)
849 self
.name
= "glX_proto_send.py (from Mesa)"
850 self
.license
= license
.bsd_license_template
% ( \
851 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
852 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
856 def printRealHeader(self
):
858 * \\file indirect_init.c
859 * Initialize indirect rendering dispatch table.
861 * \\author Kevin E. Martin <kevin@precisioninsight.com>
862 * \\author Brian Paul <brian@precisioninsight.com>
863 * \\author Ian Romanick <idr@us.ibm.com>
866 #include "indirect_init.h"
867 #include "indirect.h"
872 * No-op function used to initialize functions that have no GLX protocol
875 static int NoOp(void)
881 * Create and initialize a new GL dispatch table. The table is initialized
882 * with GLX indirect rendering protocol functions.
884 __GLapi * __glXNewIndirectAPI( void )
889 entries = _glapi_get_dispatch_table_size();
890 glAPI = (__GLapi *) Xmalloc(entries * sizeof(void *));
892 /* first, set all entries to point to no-op functions */
895 void **dispatch = (void **) glAPI;
896 for (i = 0; i < entries; i++) {
897 dispatch[i] = (void *) NoOp;
901 /* now, initialize the entries we understand */"""
903 def printRealFooter(self
):
911 def printBody(self
, api
):
912 for [name
, number
] in api
.categoryIterate():
914 preamble
= '\n /* %3u. %s */\n\n' % (int(number
), name
)
916 preamble
= '\n /* %s */\n\n' % (name
)
918 for func
in api
.functionIterateByCategory(name
):
919 if func
.client_supported_for_indirect():
920 print '%s glAPI->%s = __indirect_gl%s;' % (preamble
, func
.name
, func
.name
)
926 class PrintGlxProtoInit_h(gl_XML
.gl_print_base
):
928 gl_XML
.gl_print_base
.__init
__(self
)
930 self
.name
= "glX_proto_send.py (from Mesa)"
931 self
.license
= license
.bsd_license_template
% ( \
932 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
933 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
934 self
.header_tag
= "_INDIRECT_H_"
936 self
.last_category
= ""
940 def printRealHeader(self
):
943 * Prototypes for indirect rendering functions.
945 * \\author Kevin E. Martin <kevin@precisioninsight.com>
946 * \\author Ian Romanick <idr@us.ibm.com>
949 self
.printVisibility( "HIDDEN", "hidden" )
954 #include "glxclient.h"
956 extern HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
957 void * dest, GLboolean reply_is_always_array );
959 extern HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
960 __GLXcontext * gc, unsigned max_dim, GLint width, GLint height,
961 GLint depth, GLenum format, GLenum type, void * dest,
962 GLboolean dimensions_in_reply );
964 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
965 __GLXcontext * gc, GLint sop, GLint cmdlen );
967 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
968 __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen );
972 def printBody(self
, api
):
973 for func
in api
.functionIterateGlx():
974 params
= func
.get_parameter_string()
976 print 'extern HIDDEN %s __indirect_gl%s(%s);' % (func
.return_type
, func
.name
, params
)
978 for n
in func
.entry_points
:
979 if func
.has_different_protocol(n
):
980 asdf
= func
.static_glx_name(n
)
981 if asdf
not in func
.static_entry_points
:
982 print 'extern HIDDEN %s gl%s(%s);' % (func
.return_type
, asdf
, params
)
984 print 'GLAPI %s GLAPIENTRY gl%s(%s);' % (func
.return_type
, asdf
, params
)
991 print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys
.argv
[0]
992 print " -m output_mode Output mode can be one of 'proto', 'init_c' or 'init_h'."
993 print " -d Enable extra debug information in the generated code."
997 if __name__
== '__main__':
998 file_name
= "gl_API.xml"
1001 (args
, trail
) = getopt
.getopt(sys
.argv
[1:], "f:m:d")
1007 for (arg
,val
) in args
:
1016 printer
= PrintGlxProtoStubs()
1017 elif mode
== "init_c":
1018 printer
= PrintGlxProtoInit_c()
1019 elif mode
== "init_h":
1020 printer
= PrintGlxProtoInit_h()
1025 printer
.debug
= debug
1026 api
= gl_XML
.parse_GL_API( file_name
, glX_XML
.glx_item_factory() )
1028 printer
.Print( api
)