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) memset((void *)(%s + %u), 0, %s);' \
427 % (pc
, p
.offset
+ adjust
, p
.size_string() )
428 elif not extra_offset
:
429 print '(void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
430 % (pc
, p
.offset
+ adjust
, src_ptr
, p
.size_string() )
432 print '(void) memcpy((void *)(%s + %u + %s), (void *)(%s), %s);' \
433 % (pc
, p
.offset
+ adjust
, extra_offset
, src_ptr
, p
.size_string() )
435 def common_emit_args(self
, f
, pc
, adjust
, skip_vla
):
438 for p
in f
.parameterIterateGlxSend( not skip_vla
):
439 if p
.name
!= f
.img_reset
:
440 self
.common_emit_one_arg(p
, pc
, adjust
, extra_offset
)
442 if p
.is_variable_length():
443 temp
= p
.size_string()
445 extra_offset
+= " + %s" % (temp
)
452 def pixel_emit_args(self
, f
, pc
, large
):
453 """Emit the arguments for a pixel function. This differs from
454 common_emit_args in that pixel functions may require padding
455 be inserted (i.e., for the missing width field for
456 TexImage1D), and they may also require a 'NULL image' flag
457 be inserted before the image data."""
464 for param
in f
.parameterIterateGlxSend():
465 if not param
.is_image():
466 self
.common_emit_one_arg(param
, pc
, adjust
, None)
468 if f
.pad_after(param
):
469 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
+ param
.size()) + adjust
)
472 [dim
, width
, height
, depth
, extent
] = param
.get_dimensions()
479 print '(void) memset((void *)(%s + %u), 0, %s);' \
480 % (pc
, (param
.offset
- 4) + adjust
, param
.size_string() )
482 if param
.img_null_flag
:
484 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
- 4) + adjust
)
486 print '(void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (pc
, (param
.offset
- 4) + adjust
, param
.name
)
489 pixHeaderPtr
= "%s + %u" % (pc
, adjust
)
490 pcPtr
= "%s + %u" % (pc
, param
.offset
+ adjust
)
493 if param
.img_send_null
:
494 condition
= '(compsize > 0) && (%s != NULL)' % (param
.name
)
496 condition
= 'compsize > 0'
498 print 'if (%s) {' % (condition
)
499 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
)
501 print ' (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (pixHeaderPtr
, dim
, dim
)
504 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
)
509 def large_emit_begin(self
, f
, op_name
= None):
511 op_name
= f
.opcode_real_name()
513 print 'const GLint op = %s;' % (op_name
)
514 print 'const GLuint cmdlenLarge = cmdlen + 4;'
515 print 'GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);'
516 print '(void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);'
517 print '(void) memcpy((void *)(pc + 4), (void *)(&op), 4);'
521 def common_func_print_just_start(self
, f
, name
):
522 print ' __GLXcontext * const gc = __glXGetCurrentContext();'
524 # The only reason that single and vendor private commands need
525 # a variable called 'dpy' is becuase they use the SyncHandle
526 # macro. For whatever brain-dead reason, that macro is hard-
527 # coded to use a variable called 'dpy' instead of taking a
530 # FIXME Simplify the logic related to skip_condition and
531 # FIXME condition_list in this function. Basically, remove
532 # FIXME skip_condition, and just append the "dpy != NULL" type
533 # FIXME condition to condition_list from the start. The only
534 # FIXME reason it's done in this confusing way now is to
535 # FIXME minimize the diffs in the generated code.
538 for p
in f
.parameterIterateOutputs():
539 if p
.is_image() and (p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP"):
540 print ' const __GLXattribute * const state = gc->client_state_private;'
543 print ' Display * const dpy = gc->currentDpy;'
544 skip_condition
= "dpy != NULL"
546 skip_condition
= "gc->currentDpy != NULL"
548 skip_condition
= None
551 if f
.return_type
!= 'void':
552 print ' %s retval = (%s) 0;' % (f
.return_type
, f
.return_type
)
555 if name
!= None and name
not in f
.glx_vendorpriv_names
:
556 print '#ifndef USE_XCB'
557 self
.emit_packet_size_calculation(f
, 0)
558 if name
!= None and name
not in f
.glx_vendorpriv_names
:
562 for p
in f
.parameterIterateCounters():
563 condition_list
.append( "%s >= 0" % (p
.name
) )
564 # 'counter' parameters cannot be negative
565 print " if (%s < 0) {" % p
.name
566 print " __glXSetError(gc, GL_INVALID_VALUE);"
567 if f
.return_type
!= 'void':
574 condition_list
.append( skip_condition
)
576 if len( condition_list
) > 0:
577 if len( condition_list
) > 1:
578 skip_condition
= "(%s)" % (string
.join( condition_list
, ") && (" ))
580 skip_condition
= "%s" % (condition_list
.pop(0))
582 print ' if (__builtin_expect(%s, 1)) {' % (skip_condition
)
588 def printSingleFunction(self
, f
, name
):
589 self
.common_func_print_just_start(f
, name
)
592 print ' printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
594 if name
not in f
.glx_vendorpriv_names
:
597 print '#ifdef USE_XCB'
599 print ' printf("\\tUsing XCB.\\n");'
600 print ' xcb_connection_t *c = XGetXCBConnection(dpy);'
601 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
602 xcb_name
= 'xcb_glx%s' % convertStringForXCB(name
)
607 for p
in f
.parameterIterator():
612 if p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP":
613 extra_iparams
.append("state->storePack.swapEndian")
615 extra_iparams
.append("0")
617 # Hardcode this in. lsb_first param (apparently always GL_FALSE)
618 # also present in GetPolygonStipple, but taken care of above.
619 if xcb_name
== "xcb_glx_read_pixels":
620 extra_iparams
.append("0")
622 iparams
.append(p
.name
)
625 xcb_request
= '%s(%s)' % (xcb_name
, ", ".join(["c", "gc->currentContextTag"] + iparams
+ extra_iparams
))
628 print ' %s_reply_t *reply = %s_reply(c, %s, NULL);' % (xcb_name
, xcb_name
, xcb_request
)
629 if output
and f
.reply_always_array
:
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())
632 elif output
and not f
.reply_always_array
:
633 if not output
.is_image():
634 print ' if (%s_data_length(reply) == 0)' % (xcb_name
)
635 print ' (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output
.name
)
637 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
640 if f
.return_type
!= 'void':
641 print ' retval = reply->ret_val;'
642 print ' free(reply);'
644 print ' ' + xcb_request
+ ';'
646 # End of XCB specific.
649 if f
.parameters
!= []:
650 pc_decl
= "GLubyte const * pc ="
654 if name
in f
.glx_vendorpriv_names
:
655 print ' %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl
, f
.opcode_real_name(), f
.opcode_vendor_name(name
))
657 print ' %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl
, f
.opcode_name())
659 self
.common_emit_args(f
, "pc", 0, 0)
661 images
= f
.get_images()
665 o
= f
.command_fixed_length() - 4
666 print ' *(int32_t *)(pc + %u) = 0;' % (o
)
667 if img
.img_format
!= "GL_COLOR_INDEX" or img
.img_type
!= "GL_BITMAP":
668 print ' * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o
)
671 print ' * (int8_t *)(pc + %u) = %s;' % (o
+ 1, f
.img_reset
)
676 if f
.return_type
!= 'void':
677 return_name
= " retval"
678 return_str
= " retval = (%s)" % (f
.return_type
)
680 return_str
= " (void)"
684 for p
in f
.parameterIterateOutputs():
686 [dim
, w
, h
, d
, junk
] = p
.get_dimensions()
687 if f
.dimensions_in_reply
:
688 print " __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim
, p
.img_format
, p
.img_type
, p
.name
)
690 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
)
694 if f
.reply_always_array
:
699 # gl_parameter.size() returns the size
700 # of the entire data item. If the
701 # item is a fixed-size array, this is
702 # the size of the whole array. This
703 # is not what __glXReadReply wants. It
704 # wants the size of a single data
705 # element in the reply packet.
706 # Dividing by the array size (1 for
707 # non-arrays) gives us this.
709 s
= p
.size() / p
.get_element_count()
710 print " %s __glXReadReply(dpy, %s, %s, %s);" % (return_str
, s
, p
.name
, aa
)
714 # If a reply wasn't read to fill an output parameter,
715 # read a NULL reply to get the return value.
718 print " %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str
)
722 # Only emit the extra glFinish call for functions
723 # that don't already require a reply from the server.
724 print ' __indirect_glFinish();'
727 print ' printf( "Exit %%s.\\n", "gl%s" );' % (name
)
730 print ' UnlockDisplay(dpy); SyncHandle();'
732 if name
not in f
.glx_vendorpriv_names
:
733 print '#endif /* USE_XCB */'
736 print ' return%s;' % (return_name
)
740 def printPixelFunction(self
, f
):
741 if self
.pixel_stubs
.has_key( f
.name
):
742 # Normally gl_function::get_parameter_string could be
743 # used. However, this call needs to have the missing
744 # dimensions (e.g., a fake height value for
745 # glTexImage1D) added in.
748 for param
in f
.parameterIterateGlxSend():
752 p_string
+= ", " + param
.name
755 [dim
, junk
, junk
, junk
, junk
] = param
.get_dimensions()
757 if f
.pad_after(param
):
760 print ' %s(%s, %u%s );' % (self
.pixel_stubs
[f
.name
] , f
.opcode_name(), dim
, p_string
)
764 if self
.common_func_print_just_start(f
, None):
771 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
772 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
773 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
779 opcode
= f
.opcode_real_name()
781 print 'emit_header(gc->pc, %s, cmdlen);' % (opcode
)
783 self
.pixel_emit_args( f
, "gc->pc", 0 )
784 print 'gc->pc += cmdlen;'
785 print 'if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
791 self
.large_emit_begin(f
, opcode
)
792 self
.pixel_emit_args(f
, "pc", 1)
796 if trailer
: print trailer
800 def printRenderFunction(self
, f
):
801 # There is a class of GL functions that take a single pointer
802 # as a parameter. This pointer points to a fixed-size chunk
803 # of data, and the protocol for this functions is very
804 # regular. Since they are so regular and there are so many
805 # of them, special case them with generic functions. On
806 # x86, this saves about 26KB in the libGL.so binary.
808 if f
.variable_length_parameter() == None and len(f
.parameters
) == 1:
811 cmdlen
= f
.command_fixed_length()
812 if cmdlen
in self
.generic_sizes
:
813 print ' generic_%u_byte( %s, %s );' % (cmdlen
, f
.opcode_real_name(), p
.name
)
816 if self
.common_func_print_just_start(f
, None):
822 print 'printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
825 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
826 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
827 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
830 print 'emit_header(gc->pc, %s, cmdlen);' % (f
.opcode_real_name())
832 self
.common_emit_args(f
, "gc->pc", 4, 0)
833 print 'gc->pc += cmdlen;'
834 print 'if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
840 self
.large_emit_begin(f
)
841 self
.common_emit_args(f
, "pc", 8, 1)
843 p
= f
.variable_length_parameter()
844 print ' __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (p
.offset
+ 8, p
.name
, p
.size_string())
848 print '__indirect_glFinish();'
849 print 'printf( "Exit %%s.\\n", "gl%s" );' % (f
.name
)
851 if trailer
: print trailer
855 class PrintGlxProtoInit_c(gl_XML
.gl_print_base
):
857 gl_XML
.gl_print_base
.__init
__(self
)
859 self
.name
= "glX_proto_send.py (from Mesa)"
860 self
.license
= license
.bsd_license_template
% ( \
861 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
862 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
866 def printRealHeader(self
):
868 * \\file indirect_init.c
869 * Initialize indirect rendering dispatch table.
871 * \\author Kevin E. Martin <kevin@precisioninsight.com>
872 * \\author Brian Paul <brian@precisioninsight.com>
873 * \\author Ian Romanick <idr@us.ibm.com>
876 #include "indirect_init.h"
877 #include "indirect.h"
882 * No-op function used to initialize functions that have no GLX protocol
885 static int NoOp(void)
891 * Create and initialize a new GL dispatch table. The table is initialized
892 * with GLX indirect rendering protocol functions.
894 __GLapi * __glXNewIndirectAPI( void )
899 entries = _glapi_get_dispatch_table_size();
900 glAPI = (__GLapi *) Xmalloc(entries * sizeof(void *));
902 /* first, set all entries to point to no-op functions */
905 void **dispatch = (void **) glAPI;
906 for (i = 0; i < entries; i++) {
907 dispatch[i] = (void *) NoOp;
911 /* now, initialize the entries we understand */"""
913 def printRealFooter(self
):
921 def printBody(self
, api
):
922 for [name
, number
] in api
.categoryIterate():
924 preamble
= '\n /* %3u. %s */\n\n' % (int(number
), name
)
926 preamble
= '\n /* %s */\n\n' % (name
)
928 for func
in api
.functionIterateByCategory(name
):
929 if func
.client_supported_for_indirect():
930 print '%s glAPI->%s = __indirect_gl%s;' % (preamble
, func
.name
, func
.name
)
936 class PrintGlxProtoInit_h(gl_XML
.gl_print_base
):
938 gl_XML
.gl_print_base
.__init
__(self
)
940 self
.name
= "glX_proto_send.py (from Mesa)"
941 self
.license
= license
.bsd_license_template
% ( \
942 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
943 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
944 self
.header_tag
= "_INDIRECT_H_"
946 self
.last_category
= ""
950 def printRealHeader(self
):
953 * Prototypes for indirect rendering functions.
955 * \\author Kevin E. Martin <kevin@precisioninsight.com>
956 * \\author Ian Romanick <idr@us.ibm.com>
959 self
.printVisibility( "HIDDEN", "hidden" )
964 #include "glxclient.h"
966 extern HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
967 void * dest, GLboolean reply_is_always_array );
969 extern HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
970 __GLXcontext * gc, unsigned max_dim, GLint width, GLint height,
971 GLint depth, GLenum format, GLenum type, void * dest,
972 GLboolean dimensions_in_reply );
974 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
975 __GLXcontext * gc, GLint sop, GLint cmdlen );
977 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
978 __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen );
982 def printBody(self
, api
):
983 for func
in api
.functionIterateGlx():
984 params
= func
.get_parameter_string()
986 print 'extern HIDDEN %s __indirect_gl%s(%s);' % (func
.return_type
, func
.name
, params
)
988 for n
in func
.entry_points
:
989 if func
.has_different_protocol(n
):
990 asdf
= func
.static_glx_name(n
)
991 if asdf
not in func
.static_entry_points
:
992 print 'extern HIDDEN %s gl%s(%s);' % (func
.return_type
, asdf
, params
)
994 print 'GLAPI %s GLAPIENTRY gl%s(%s);' % (func
.return_type
, asdf
, params
)
1001 print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys
.argv
[0]
1002 print " -m output_mode Output mode can be one of 'proto', 'init_c' or 'init_h'."
1003 print " -d Enable extra debug information in the generated code."
1007 if __name__
== '__main__':
1008 file_name
= "gl_API.xml"
1011 (args
, trail
) = getopt
.getopt(sys
.argv
[1:], "f:m:d")
1017 for (arg
,val
) in args
:
1026 printer
= PrintGlxProtoStubs()
1027 elif mode
== "init_c":
1028 printer
= PrintGlxProtoInit_c()
1029 elif mode
== "init_h":
1030 printer
= PrintGlxProtoInit_h()
1035 printer
.debug
= debug
1036 api
= gl_XML
.parse_GL_API( file_name
, glX_XML
.glx_item_factory() )
1038 printer
.Print( api
)