08f332f504a3bd93121a8a5859a77e7dfbe9af5e
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 "glapidispatch.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 '#ifndef __GNUC__'
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, struct glx_context * 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( struct glx_context * 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( struct glx_context * 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 ' struct glx_context * const gc = __glXGetCurrentContext();'
376 print '#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)'
377 print ' if (gc->driContext) {'
378 print ' %sCALL_%s(GET_DISPATCH(), (%s));' % (ret_string
, func
.name
, func
.get_called_parameter_string())
385 print '#define %s %d' % (func
.opcode_name(), func
.opcode_value())
387 print '%s __indirect_gl%s(%s)' % (func
.return_type
, name
, func
.get_parameter_string())
391 if func
.glx_rop
!= 0 or func
.vectorequiv
!= None:
393 self
.printPixelFunction(func
)
395 self
.printRenderFunction(func
)
396 elif func
.glx_sop
!= 0 or func
.glx_vendorpriv
!= 0:
397 self
.printSingleFunction(func
, name
)
400 print "/* Missing GLX protocol for %s. */" % (name
)
406 def print_generic_function(self
, n
):
408 print """static FASTCALL NOINLINE void
409 generic_%u_byte( GLint rop, const void * ptr )
411 struct glx_context * const gc = __glXGetCurrentContext();
412 const GLuint cmdlen = %u;
414 emit_header(gc->pc, rop, cmdlen);
415 (void) memcpy((void *)(gc->pc + 4), ptr, %u);
417 if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }
419 """ % (n
, size
+ 4, size
)
423 def common_emit_one_arg(self
, p
, pc
, adjust
, extra_offset
):
427 src_ptr
= "&" + p
.name
430 print '(void) memset((void *)(%s + %u), 0, %s);' \
431 % (pc
, p
.offset
+ adjust
, p
.size_string() )
432 elif not extra_offset
:
433 print '(void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
434 % (pc
, p
.offset
+ adjust
, src_ptr
, p
.size_string() )
436 print '(void) memcpy((void *)(%s + %u + %s), (void *)(%s), %s);' \
437 % (pc
, p
.offset
+ adjust
, extra_offset
, src_ptr
, p
.size_string() )
439 def common_emit_args(self
, f
, pc
, adjust
, skip_vla
):
442 for p
in f
.parameterIterateGlxSend( not skip_vla
):
443 if p
.name
!= f
.img_reset
:
444 self
.common_emit_one_arg(p
, pc
, adjust
, extra_offset
)
446 if p
.is_variable_length():
447 temp
= p
.size_string()
449 extra_offset
+= " + %s" % (temp
)
456 def pixel_emit_args(self
, f
, pc
, large
):
457 """Emit the arguments for a pixel function. This differs from
458 common_emit_args in that pixel functions may require padding
459 be inserted (i.e., for the missing width field for
460 TexImage1D), and they may also require a 'NULL image' flag
461 be inserted before the image data."""
468 for param
in f
.parameterIterateGlxSend():
469 if not param
.is_image():
470 self
.common_emit_one_arg(param
, pc
, adjust
, None)
472 if f
.pad_after(param
):
473 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
+ param
.size()) + adjust
)
476 [dim
, width
, height
, depth
, extent
] = param
.get_dimensions()
483 print '(void) memset((void *)(%s + %u), 0, %s);' \
484 % (pc
, (param
.offset
- 4) + adjust
, param
.size_string() )
486 if param
.img_null_flag
:
488 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
- 4) + adjust
)
490 print '(void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (pc
, (param
.offset
- 4) + adjust
, param
.name
)
493 pixHeaderPtr
= "%s + %u" % (pc
, adjust
)
494 pcPtr
= "%s + %u" % (pc
, param
.offset
+ adjust
)
497 if param
.img_send_null
:
498 condition
= '(compsize > 0) && (%s != NULL)' % (param
.name
)
500 condition
= 'compsize > 0'
502 print 'if (%s) {' % (condition
)
503 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
)
505 print ' (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (pixHeaderPtr
, dim
, dim
)
508 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
)
513 def large_emit_begin(self
, f
, op_name
= None):
515 op_name
= f
.opcode_real_name()
517 print 'const GLint op = %s;' % (op_name
)
518 print 'const GLuint cmdlenLarge = cmdlen + 4;'
519 print 'GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);'
520 print '(void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);'
521 print '(void) memcpy((void *)(pc + 4), (void *)(&op), 4);'
525 def common_func_print_just_start(self
, f
, name
):
526 print ' struct glx_context * const gc = __glXGetCurrentContext();'
528 # The only reason that single and vendor private commands need
529 # a variable called 'dpy' is becuase they use the SyncHandle
530 # macro. For whatever brain-dead reason, that macro is hard-
531 # coded to use a variable called 'dpy' instead of taking a
534 # FIXME Simplify the logic related to skip_condition and
535 # FIXME condition_list in this function. Basically, remove
536 # FIXME skip_condition, and just append the "dpy != NULL" type
537 # FIXME condition to condition_list from the start. The only
538 # FIXME reason it's done in this confusing way now is to
539 # FIXME minimize the diffs in the generated code.
542 for p
in f
.parameterIterateOutputs():
543 if p
.is_image() and (p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP"):
544 print ' const __GLXattribute * const state = gc->client_state_private;'
547 print ' Display * const dpy = gc->currentDpy;'
548 skip_condition
= "dpy != NULL"
550 skip_condition
= "gc->currentDpy != NULL"
552 skip_condition
= None
555 if f
.return_type
!= 'void':
556 print ' %s retval = (%s) 0;' % (f
.return_type
, f
.return_type
)
559 if name
!= None and name
not in f
.glx_vendorpriv_names
:
560 print '#ifndef USE_XCB'
561 self
.emit_packet_size_calculation(f
, 0)
562 if name
!= None and name
not in f
.glx_vendorpriv_names
:
566 for p
in f
.parameterIterateCounters():
567 condition_list
.append( "%s >= 0" % (p
.name
) )
568 # 'counter' parameters cannot be negative
569 print " if (%s < 0) {" % p
.name
570 print " __glXSetError(gc, GL_INVALID_VALUE);"
571 if f
.return_type
!= 'void':
578 condition_list
.append( skip_condition
)
580 if len( condition_list
) > 0:
581 if len( condition_list
) > 1:
582 skip_condition
= "(%s)" % (string
.join( condition_list
, ") && (" ))
584 skip_condition
= "%s" % (condition_list
.pop(0))
586 print ' if (__builtin_expect(%s, 1)) {' % (skip_condition
)
592 def printSingleFunction(self
, f
, name
):
593 self
.common_func_print_just_start(f
, name
)
596 print ' printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
598 if name
not in f
.glx_vendorpriv_names
:
601 print '#ifdef USE_XCB'
603 print ' printf("\\tUsing XCB.\\n");'
604 print ' xcb_connection_t *c = XGetXCBConnection(dpy);'
605 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
606 xcb_name
= 'xcb_glx%s' % convertStringForXCB(name
)
611 for p
in f
.parameterIterator():
616 if p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP":
617 extra_iparams
.append("state->storePack.swapEndian")
619 extra_iparams
.append("0")
621 # Hardcode this in. lsb_first param (apparently always GL_FALSE)
622 # also present in GetPolygonStipple, but taken care of above.
623 if xcb_name
== "xcb_glx_read_pixels":
624 extra_iparams
.append("0")
626 iparams
.append(p
.name
)
629 xcb_request
= '%s(%s)' % (xcb_name
, ", ".join(["c", "gc->currentContextTag"] + iparams
+ extra_iparams
))
632 print ' %s_reply_t *reply = %s_reply(c, %s, NULL);' % (xcb_name
, xcb_name
, xcb_request
)
633 if output
and f
.reply_always_array
:
634 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
636 elif output
and not f
.reply_always_array
:
637 if not output
.is_image():
638 print ' if (%s_data_length(reply) == 0)' % (xcb_name
)
639 print ' (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output
.name
)
641 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
644 if f
.return_type
!= 'void':
645 print ' retval = reply->ret_val;'
646 print ' free(reply);'
648 print ' ' + xcb_request
+ ';'
650 # End of XCB specific.
653 if f
.parameters
!= []:
654 pc_decl
= "GLubyte const * pc ="
658 if name
in f
.glx_vendorpriv_names
:
659 print ' %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl
, f
.opcode_real_name(), f
.opcode_vendor_name(name
))
661 print ' %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl
, f
.opcode_name())
663 self
.common_emit_args(f
, "pc", 0, 0)
665 images
= f
.get_images()
669 o
= f
.command_fixed_length() - 4
670 print ' *(int32_t *)(pc + %u) = 0;' % (o
)
671 if img
.img_format
!= "GL_COLOR_INDEX" or img
.img_type
!= "GL_BITMAP":
672 print ' * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o
)
675 print ' * (int8_t *)(pc + %u) = %s;' % (o
+ 1, f
.img_reset
)
680 if f
.return_type
!= 'void':
681 return_name
= " retval"
682 return_str
= " retval = (%s)" % (f
.return_type
)
684 return_str
= " (void)"
688 for p
in f
.parameterIterateOutputs():
690 [dim
, w
, h
, d
, junk
] = p
.get_dimensions()
691 if f
.dimensions_in_reply
:
692 print " __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim
, p
.img_format
, p
.img_type
, p
.name
)
694 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
)
698 if f
.reply_always_array
:
703 # gl_parameter.size() returns the size
704 # of the entire data item. If the
705 # item is a fixed-size array, this is
706 # the size of the whole array. This
707 # is not what __glXReadReply wants. It
708 # wants the size of a single data
709 # element in the reply packet.
710 # Dividing by the array size (1 for
711 # non-arrays) gives us this.
713 s
= p
.size() / p
.get_element_count()
714 print " %s __glXReadReply(dpy, %s, %s, %s);" % (return_str
, s
, p
.name
, aa
)
718 # If a reply wasn't read to fill an output parameter,
719 # read a NULL reply to get the return value.
722 print " %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str
)
726 # Only emit the extra glFinish call for functions
727 # that don't already require a reply from the server.
728 print ' __indirect_glFinish();'
731 print ' printf( "Exit %%s.\\n", "gl%s" );' % (name
)
734 print ' UnlockDisplay(dpy); SyncHandle();'
736 if name
not in f
.glx_vendorpriv_names
:
737 print '#endif /* USE_XCB */'
740 print ' return%s;' % (return_name
)
744 def printPixelFunction(self
, f
):
745 if self
.pixel_stubs
.has_key( f
.name
):
746 # Normally gl_function::get_parameter_string could be
747 # used. However, this call needs to have the missing
748 # dimensions (e.g., a fake height value for
749 # glTexImage1D) added in.
752 for param
in f
.parameterIterateGlxSend():
756 p_string
+= ", " + param
.name
759 [dim
, junk
, junk
, junk
, junk
] = param
.get_dimensions()
761 if f
.pad_after(param
):
764 print ' %s(%s, %u%s );' % (self
.pixel_stubs
[f
.name
] , f
.opcode_name(), dim
, p_string
)
768 if self
.common_func_print_just_start(f
, None):
775 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
776 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
777 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
783 opcode
= f
.opcode_real_name()
785 print 'emit_header(gc->pc, %s, cmdlen);' % (opcode
)
787 self
.pixel_emit_args( f
, "gc->pc", 0 )
788 print 'gc->pc += cmdlen;'
789 print 'if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
795 self
.large_emit_begin(f
, opcode
)
796 self
.pixel_emit_args(f
, "pc", 1)
800 if trailer
: print trailer
804 def printRenderFunction(self
, f
):
805 # There is a class of GL functions that take a single pointer
806 # as a parameter. This pointer points to a fixed-size chunk
807 # of data, and the protocol for this functions is very
808 # regular. Since they are so regular and there are so many
809 # of them, special case them with generic functions. On
810 # x86, this saves about 26KB in the libGL.so binary.
812 if f
.variable_length_parameter() == None and len(f
.parameters
) == 1:
815 cmdlen
= f
.command_fixed_length()
816 if cmdlen
in self
.generic_sizes
:
817 print ' generic_%u_byte( %s, %s );' % (cmdlen
, f
.opcode_real_name(), p
.name
)
820 if self
.common_func_print_just_start(f
, None):
826 print 'printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
829 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
830 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
831 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
834 print 'emit_header(gc->pc, %s, cmdlen);' % (f
.opcode_real_name())
836 self
.common_emit_args(f
, "gc->pc", 4, 0)
837 print 'gc->pc += cmdlen;'
838 print 'if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
844 self
.large_emit_begin(f
)
845 self
.common_emit_args(f
, "pc", 8, 1)
847 p
= f
.variable_length_parameter()
848 print ' __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (p
.offset
+ 8, p
.name
, p
.size_string())
852 print '__indirect_glFinish();'
853 print 'printf( "Exit %%s.\\n", "gl%s" );' % (f
.name
)
855 if trailer
: print trailer
859 class PrintGlxProtoInit_c(gl_XML
.gl_print_base
):
861 gl_XML
.gl_print_base
.__init
__(self
)
863 self
.name
= "glX_proto_send.py (from Mesa)"
864 self
.license
= license
.bsd_license_template
% ( \
865 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
866 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
870 def printRealHeader(self
):
872 * \\file indirect_init.c
873 * Initialize indirect rendering dispatch table.
875 * \\author Kevin E. Martin <kevin@precisioninsight.com>
876 * \\author Brian Paul <brian@precisioninsight.com>
877 * \\author Ian Romanick <idr@us.ibm.com>
880 #include "indirect_init.h"
881 #include "indirect.h"
886 * No-op function used to initialize functions that have no GLX protocol
889 static int NoOp(void)
895 * Create and initialize a new GL dispatch table. The table is initialized
896 * with GLX indirect rendering protocol functions.
898 __GLapi * __glXNewIndirectAPI( void )
903 entries = _glapi_get_dispatch_table_size();
904 glAPI = (__GLapi *) Xmalloc(entries * sizeof(void *));
906 /* first, set all entries to point to no-op functions */
909 void **dispatch = (void **) glAPI;
910 for (i = 0; i < entries; i++) {
911 dispatch[i] = (void *) NoOp;
915 /* now, initialize the entries we understand */"""
917 def printRealFooter(self
):
925 def printBody(self
, api
):
926 for [name
, number
] in api
.categoryIterate():
928 preamble
= '\n /* %3u. %s */\n\n' % (int(number
), name
)
930 preamble
= '\n /* %s */\n\n' % (name
)
932 for func
in api
.functionIterateByCategory(name
):
933 if func
.client_supported_for_indirect():
934 print '%s glAPI->%s = __indirect_gl%s;' % (preamble
, func
.name
, func
.name
)
940 class PrintGlxProtoInit_h(gl_XML
.gl_print_base
):
942 gl_XML
.gl_print_base
.__init
__(self
)
944 self
.name
= "glX_proto_send.py (from Mesa)"
945 self
.license
= license
.bsd_license_template
% ( \
946 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
947 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
948 self
.header_tag
= "_INDIRECT_H_"
950 self
.last_category
= ""
954 def printRealHeader(self
):
957 * Prototypes for indirect rendering functions.
959 * \\author Kevin E. Martin <kevin@precisioninsight.com>
960 * \\author Ian Romanick <idr@us.ibm.com>
963 self
.printVisibility( "HIDDEN", "hidden" )
968 #include "glxclient.h"
970 extern HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
971 void * dest, GLboolean reply_is_always_array );
973 extern HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
974 struct glx_context * gc, unsigned max_dim, GLint width, GLint height,
975 GLint depth, GLenum format, GLenum type, void * dest,
976 GLboolean dimensions_in_reply );
978 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
979 struct glx_context * gc, GLint sop, GLint cmdlen );
981 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
982 struct glx_context * gc, GLint code, GLint vop, GLint cmdlen );
986 def printBody(self
, api
):
987 for func
in api
.functionIterateGlx():
988 params
= func
.get_parameter_string()
990 print 'extern HIDDEN %s __indirect_gl%s(%s);' % (func
.return_type
, func
.name
, params
)
992 for n
in func
.entry_points
:
993 if func
.has_different_protocol(n
):
994 asdf
= func
.static_glx_name(n
)
995 if asdf
not in func
.static_entry_points
:
996 print 'extern HIDDEN %s gl%s(%s);' % (func
.return_type
, asdf
, params
)
998 print 'GLAPI %s GLAPIENTRY gl%s(%s);' % (func
.return_type
, asdf
, params
)
1005 print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys
.argv
[0]
1006 print " -m output_mode Output mode can be one of 'proto', 'init_c' or 'init_h'."
1007 print " -d Enable extra debug information in the generated code."
1011 if __name__
== '__main__':
1012 file_name
= "gl_API.xml"
1015 (args
, trail
) = getopt
.getopt(sys
.argv
[1:], "f:m:d")
1021 for (arg
,val
) in args
:
1030 printer
= PrintGlxProtoStubs()
1031 elif mode
== "init_c":
1032 printer
= PrintGlxProtoInit_c()
1033 elif mode
== "init_h":
1034 printer
= PrintGlxProtoInit_h()
1039 printer
.debug
= debug
1040 api
= gl_XML
.parse_GL_API( file_name
, glX_XML
.glx_item_factory() )
1042 printer
.Print( api
)