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/xcl.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
, indent
, adjust
, extra_offset
):
404 src_ptr
= "&" + p
.name
407 print '%s (void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
408 % (indent
, pc
, p
.offset
+ adjust
, src_ptr
, p
.size_string() )
410 print '%s (void) memcpy((void *)(%s + %u + %s), (void *)(%s), %s);' \
411 % (indent
, pc
, p
.offset
+ adjust
, extra_offset
, src_ptr
, p
.size_string() )
413 def common_emit_args(self
, f
, pc
, indent
, 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
, indent
, 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
, indent
, 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
, indent
, adjust
, None)
446 if f
.pad_after(param
):
447 print '%s (void) memcpy((void *)(%s + %u), zero, 4);' % (indent
, pc
, (param
.offset
+ param
.size()) + adjust
)
450 [dim
, width
, height
, depth
, extent
] = param
.get_dimensions()
456 if param
.img_null_flag
:
458 print '%s (void) memcpy((void *)(%s + %u), zero, 4);' % (indent
, pc
, (param
.offset
- 4) + adjust
)
460 print '%s (void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (indent
, 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 '%s if (%s) {' % (indent
, condition
)
473 print '%s (*gc->fillImage)(gc, %s, %s, %s, %s, %s, %s, %s, %s, %s);' % (indent
, dim_str
, width
, height
, depth
, param
.img_format
, param
.img_type
, param
.name
, pcPtr
, pixHeaderPtr
)
474 print '%s }' % (indent
)
475 print '%s else {' % (indent
)
476 print '%s (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (indent
, pixHeaderPtr
, dim
, dim
)
477 print '%s }' % (indent
)
479 print '%s __glXSendLargeImage(gc, compsize, %s, %s, %s, %s, %s, %s, %s, %s, %s);' % (indent
, dim_str
, width
, height
, depth
, param
.img_format
, param
.img_type
, param
.name
, pcPtr
, pixHeaderPtr
)
484 def large_emit_begin(self
, indent
, f
, op_name
= None):
486 op_name
= f
.opcode_real_name()
488 print '%s const GLint op = %s;' % (indent
, op_name
)
489 print '%s const GLuint cmdlenLarge = cmdlen + 4;' % (indent
)
490 print '%s GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);' % (indent
)
491 print '%s (void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);' % (indent
)
492 print '%s (void) memcpy((void *)(pc + 4), (void *)(&op), 4);' % (indent
)
496 def common_func_print_just_start(self
, f
):
497 print ' __GLXcontext * const gc = __glXGetCurrentContext();'
499 # The only reason that single and vendor private commands need
500 # a variable called 'dpy' is becuase they use the SyncHandle
501 # macro. For whatever brain-dead reason, that macro is hard-
502 # coded to use a variable called 'dpy' instead of taking a
505 # FIXME Simplify the logic related to skip_condition and
506 # FIXME condition_list in this function. Basically, remove
507 # FIXME skip_condition, and just append the "dpy != NULL" type
508 # FIXME condition to condition_list from the start. The only
509 # FIXME reason it's done in this confusing way now is to
510 # FIXME minimize the diffs in the generated code.
513 for p
in f
.parameterIterateOutputs():
515 print ' const __GLXattribute * const state = gc->client_state_private;'
518 print ' Display * const dpy = gc->currentDpy;'
519 skip_condition
= "dpy != NULL"
521 skip_condition
= "gc->currentDpy != NULL"
523 skip_condition
= None
526 if f
.return_type
!= 'void':
527 print ' %s retval = (%s) 0;' % (f
.return_type
, f
.return_type
)
530 self
.emit_packet_size_calculation(f
, 0)
533 for p
in f
.parameterIterateCounters():
534 condition_list
.append( "%s >= 0" % (p
.name
) )
537 condition_list
.append( skip_condition
)
539 if len( condition_list
) > 0:
540 if len( condition_list
) > 1:
541 skip_condition
= "(%s)" % (string
.join( condition_list
, ") && (" ))
543 skip_condition
= "%s" % (condition_list
.pop(0))
545 print ' if (__builtin_expect(%s, 1)) {' % (skip_condition
)
551 def printSingleFunction(self
, f
):
552 self
.common_func_print_just_start(f
)
555 print ' printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
557 if f
.glx_vendorpriv
== 0:
560 print '#ifdef USE_XCB'
562 print ' printf("\\tUsing XCB.\\n");'
563 print ' xcb_connection_t *c = XGetXCBConnection(dpy);'
564 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
565 xcb_name
= 'xcb_glx%s' % convertStringForXCB(f
.name
)
570 for p
in f
.parameterIterator():
575 if p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP":
576 extra_iparams
.append("state->storePack.swapEndian")
578 extra_iparams
.append("0")
580 # Hardcode this in. lsb_first param (apparently always GL_FALSE)
581 # also present in GetPolygonStipple, but taken care of above.
582 if xcb_name
== "xcb_glx_read_pixels":
583 extra_iparams
.append("0")
585 iparams
.append(p
.name
)
588 xcb_request
= '%s(%s)' % (xcb_name
, ", ".join(["c", "gc->currentContextTag"] + iparams
+ extra_iparams
))
591 print ' %s_reply_t *reply = %s_reply(c, %s, NULL);' % (xcb_name
, xcb_name
, xcb_request
)
592 if output
and f
.reply_always_array
:
593 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
595 elif output
and not f
.reply_always_array
:
596 if not output
.is_image():
597 print ' if (%s_data_length(reply) == 0)' % (xcb_name
)
598 print ' (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output
.name
)
600 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
603 if f
.return_type
!= 'void':
604 print ' retval = reply->ret_val;'
605 print ' free(reply);'
607 print ' ' + xcb_request
+ ';'
609 # End of XCB specific.
612 if f
.parameters
!= []:
613 pc_decl
= "GLubyte const * pc ="
617 if f
.glx_vendorpriv
!= 0:
618 print ' %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl
, f
.opcode_real_name(), f
.opcode_name())
620 print ' %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl
, f
.opcode_name())
622 self
.common_emit_args(f
, "pc", " ", 0, 0)
624 images
= f
.get_images()
628 o
= f
.command_fixed_length() - 4
629 print ' *(int32_t *)(pc + %u) = 0;' % (o
)
630 if img
.img_format
!= "GL_COLOR_INDEX" or img
.img_type
!= "GL_BITMAP":
631 print ' * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o
)
634 print ' * (int8_t *)(pc + %u) = %s;' % (o
+ 1, f
.img_reset
)
639 if f
.return_type
!= 'void':
640 return_name
= " retval"
641 return_str
= " retval = (%s)" % (f
.return_type
)
643 return_str
= " (void)"
647 for p
in f
.parameterIterateOutputs():
649 [dim
, w
, h
, d
, junk
] = p
.get_dimensions()
650 if f
.dimensions_in_reply
:
651 print " __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim
, p
.img_format
, p
.img_type
, p
.name
)
653 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
)
657 if f
.reply_always_array
:
662 # gl_parameter.size() returns the size
663 # of the entire data item. If the
664 # item is a fixed-size array, this is
665 # the size of the whole array. This
666 # is not what __glXReadReply wants. It
667 # wants the size of a single data
668 # element in the reply packet.
669 # Dividing by the array size (1 for
670 # non-arrays) gives us this.
672 s
= p
.size() / p
.get_element_count()
673 print " %s __glXReadReply(dpy, %s, %s, %s);" % (return_str
, s
, p
.name
, aa
)
677 # If a reply wasn't read to fill an output parameter,
678 # read a NULL reply to get the return value.
681 print " %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str
)
685 # Only emit the extra glFinish call for functions
686 # that don't already require a reply from the server.
687 print ' __indirect_glFinish();'
690 print ' printf( "Exit %%s.\\n", "gl%s" );' % (f
.name
)
693 print ' UnlockDisplay(dpy); SyncHandle();'
695 if f
.glx_vendorpriv
== 0:
696 print '#endif /* USE_XCB */'
699 print ' return%s;' % (return_name
)
703 def printPixelFunction(self
, f
):
704 if self
.pixel_stubs
.has_key( f
.name
):
705 # Normally gl_function::get_parameter_string could be
706 # used. However, this call needs to have the missing
707 # dimensions (e.g., a fake height value for
708 # glTexImage1D) added in.
711 for param
in f
.parameterIterateGlxSend():
712 p_string
+= ", " + param
.name
715 [dim
, junk
, junk
, junk
, junk
] = param
.get_dimensions()
717 if f
.pad_after(param
):
720 print ' %s(%s, %u%s );' % (self
.pixel_stubs
[f
.name
] , f
.opcode_name(), dim
, p_string
)
724 if self
.common_func_print_just_start(f
):
733 print '%s if (cmdlen <= gc->maxSmallRenderCommandSize) {' % (indent
)
734 print '%s if ( (gc->pc + cmdlen) > gc->bufEnd ) {' % (indent
)
735 print '%s (void) __glXFlushRenderBuffer(gc, gc->pc);' % (indent
)
736 print '%s }' % (indent
)
742 opcode
= f
.opcode_real_name()
744 print '%s emit_header(gc->pc, %s, cmdlen);' % (indent
, opcode
)
746 self
.pixel_emit_args( f
, "gc->pc", indent
, 0 )
747 print '%s gc->pc += cmdlen;' % (indent
)
748 print '%s if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent
)
751 print '%s}' % (indent
)
752 print '%selse {' % (indent
)
754 self
.large_emit_begin(indent
, f
, opcode
)
755 self
.pixel_emit_args( f
, "pc", indent
, 1 )
757 print '%s}' % (indent
)
759 if trailer
: print trailer
763 def printRenderFunction(self
, f
):
764 # There is a class of GL functions that take a single pointer
765 # as a parameter. This pointer points to a fixed-size chunk
766 # of data, and the protocol for this functions is very
767 # regular. Since they are so regular and there are so many
768 # of them, special case them with generic functions. On
769 # x86, this saves about 26KB in the libGL.so binary.
771 if f
.variable_length_parameter() == None and len(f
.parameters
) == 1:
774 cmdlen
= f
.command_fixed_length()
775 if cmdlen
in self
.generic_sizes
:
776 print ' generic_%u_byte( %s, %s );' % (cmdlen
, f
.opcode_real_name(), p
.name
)
779 if self
.common_func_print_just_start(f
):
787 print '%s printf( "Enter %%s...\\n", "gl%s" );' % (indent
, f
.name
)
790 print '%s if (cmdlen <= gc->maxSmallRenderCommandSize) {' % (indent
)
791 print '%s if ( (gc->pc + cmdlen) > gc->bufEnd ) {' % (indent
)
792 print '%s (void) __glXFlushRenderBuffer(gc, gc->pc);' % (indent
)
793 print '%s }' % (indent
)
796 print '%s emit_header(gc->pc, %s, cmdlen);' % (indent
, f
.opcode_real_name())
798 self
.common_emit_args(f
, "gc->pc", indent
, 4, 0)
799 print '%s gc->pc += cmdlen;' % (indent
)
800 print '%s if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent
)
803 print '%s}' % (indent
)
804 print '%selse {' % (indent
)
806 self
.large_emit_begin(indent
, f
)
807 self
.common_emit_args(f
, "pc", indent
, 8, 1)
809 p
= f
.variable_length_parameter()
810 print '%s __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (indent
, p
.offset
+ 8, p
.name
, p
.size_string())
811 print '%s}' % (indent
)
814 print '%s __indirect_glFinish();' % (indent
)
815 print '%s printf( "Exit %%s.\\n", "gl%s" );' % (indent
, f
.name
)
817 if trailer
: print trailer
821 class PrintGlxProtoInit_c(gl_XML
.gl_print_base
):
823 gl_XML
.gl_print_base
.__init
__(self
)
825 self
.name
= "glX_proto_send.py (from Mesa)"
826 self
.license
= license
.bsd_license_template
% ( \
827 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
828 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
832 def printRealHeader(self
):
834 * \\file indirect_init.c
835 * Initialize indirect rendering dispatch table.
837 * \\author Kevin E. Martin <kevin@precisioninsight.com>
838 * \\author Brian Paul <brian@precisioninsight.com>
839 * \\author Ian Romanick <idr@us.ibm.com>
842 #include "indirect_init.h"
843 #include "indirect.h"
848 * No-op function used to initialize functions that have no GLX protocol
851 static int NoOp(void)
857 * Create and initialize a new GL dispatch table. The table is initialized
858 * with GLX indirect rendering protocol functions.
860 __GLapi * __glXNewIndirectAPI( void )
865 entries = _glapi_get_dispatch_table_size();
866 glAPI = (__GLapi *) Xmalloc(entries * sizeof(void *));
868 /* first, set all entries to point to no-op functions */
871 void **dispatch = (void **) glAPI;
872 for (i = 0; i < entries; i++) {
873 dispatch[i] = (void *) NoOp;
877 /* now, initialize the entries we understand */"""
879 def printRealFooter(self
):
887 def printCategory(self
, category_group
, show_num
):
888 cat_keys
= category_group
.keys()
890 for cat_num
in cat_keys
:
892 for offset
in category_group
[ cat_num
]:
893 [cat_name
, func_name
] = category_group
[ cat_num
][ offset
]
898 print ' /* %3u. %s */' % (cat_num
, cat_name
)
900 print ' /* %s */' % (cat_name
)
904 print ' glAPI->%s = __indirect_gl%s;' % (func_name
, func_name
)
907 def printBody(self
, api
):
910 other_categories
= {}
913 for func
in api
.functionIterateGlx():
914 [cat
, num
] = api
.get_category_for_name( func
.name
)
916 # There are three groups of "categories" that we
917 # care about here. We want to separate the core GL
918 # version categories from extensions. We also want to
919 # separate the ARB extensions from the non-ARB
922 # This is done by first trying to convert the category
923 # name to a floating point number. All core GL
924 # versions are of the form "N.M" where both N and M
925 # are integers. If the cast to float fails, an
926 # exception will be thrown. Once down that path,
927 # we can look at the start of the extension string.
928 # If it begins with "GL_ARB_", it's an ARB extension.
930 # Once the categories are separated, the are ordered
931 # by number. The un-numbered non-ARB extensions
932 # (e.g., GL_INGR_blend_func_separate) are assigned
933 # arbitrary numbers starting at 1000.
935 # FIXME In order to maintain repeatability, the
936 # FIXME unnumbered extensions should be put in their
937 # FIXME own dictionary and ordered by name (since they
938 # FIXME have no number).
942 if not core_categories
.has_key( num
):
943 core_categories
[ num
] = {}
945 core_categories
[ num
][ func
.offset
] = [cat
, func
.name
]
954 if cat
.startswith( "GL_ARB_" ):
955 if not arb_categories
.has_key( num
):
956 arb_categories
[ num
] = {}
958 arb_categories
[ num
][ func
.offset
] = [cat
, func
.name
]
960 if not other_categories
.has_key( num
):
961 other_categories
[ num
] = {}
963 other_categories
[ num
][ func
.offset
] = [cat
, func
.name
]
965 self
.printCategory( core_categories
, 0 )
966 self
.printCategory( arb_categories
, 1 )
967 self
.printCategory( other_categories
, 1 )
971 class PrintGlxProtoInit_h(gl_XML
.gl_print_base
):
973 gl_XML
.gl_print_base
.__init
__(self
)
975 self
.name
= "glX_proto_send.py (from Mesa)"
976 self
.license
= license
.bsd_license_template
% ( \
977 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
978 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
979 self
.header_tag
= "_INDIRECT_H_"
981 self
.last_category
= ""
985 def printRealHeader(self
):
988 * Prototypes for indirect rendering functions.
990 * \\author Kevin E. Martin <kevin@precisioninsight.com>
991 * \\author Ian Romanick <idr@us.ibm.com>
994 self
.printVisibility( "HIDDEN", "hidden" )
999 #include "glxclient.h"
1001 extern HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
1002 void * dest, GLboolean reply_is_always_array );
1004 extern HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
1005 __GLXcontext * gc, unsigned max_dim, GLint width, GLint height,
1006 GLint depth, GLenum format, GLenum type, void * dest,
1007 GLboolean dimensions_in_reply );
1009 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
1010 __GLXcontext * gc, GLint sop, GLint cmdlen );
1012 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
1013 __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen );
1017 def printBody(self
, api
):
1018 for func
in api
.functionIterateGlx():
1019 print 'extern HIDDEN %s __indirect_gl%s(%s);' % (func
.return_type
, func
.name
, func
.get_parameter_string())
1023 print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys
.argv
[0]
1024 print " -m output_mode Output mode can be one of 'proto', 'init_c' or 'init_h'."
1025 print " -d Enable extra debug information in the generated code."
1029 if __name__
== '__main__':
1030 file_name
= "gl_API.xml"
1033 (args
, trail
) = getopt
.getopt(sys
.argv
[1:], "f:m:d")
1039 for (arg
,val
) in args
:
1048 printer
= PrintGlxProtoStubs()
1049 elif mode
== "init_c":
1050 printer
= PrintGlxProtoInit_c()
1051 elif mode
== "init_h":
1052 printer
= PrintGlxProtoInit_h()
1057 printer
.debug
= debug
1058 api
= gl_XML
.parse_GL_API( file_name
, glX_XML
.glx_item_factory() )
1060 printer
.Print( api
)