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 "glapi.h"'
170 print '#include "glthread.h"'
171 print '#include <GL/glxproto.h>'
172 print '#ifdef USE_XCB'
173 print '#include <X11/Xlib-xcb.h>'
174 print '#include <xcb/xcb.h>'
175 print '#include <xcb/glx.h>'
176 print '#endif /* USE_XCB */'
179 print '#define __GLX_PAD(n) (((n) + 3) & ~3)'
184 print '#ifndef __GNUC__'
185 print '# define __builtin_expect(x, y) x'
188 print '/* If the size and opcode values are known at compile-time, this will, on'
189 print ' * x86 at least, emit them with a single instruction.'
191 print '#define emit_header(dest, op, size) \\'
192 print ' do { union { short s[2]; int i; } temp; \\'
193 print ' temp.s[0] = (size); temp.s[1] = (op); \\'
194 print ' *((int *)(dest)) = temp.i; } while(0)'
196 print """NOINLINE CARD32
197 __glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array )
199 xGLXSingleReply reply;
201 (void) _XReply(dpy, (xReply *) & reply, 0, False);
203 if ((reply.length > 0) || reply_is_always_array) {
204 const GLint bytes = (reply_is_always_array)
205 ? (4 * reply.length) : (reply.size * size);
206 const GLint extra = 4 - (bytes & 3);
208 _XRead(dpy, dest, bytes);
210 _XEatData(dpy, extra);
214 (void) memcpy( dest, &(reply.pad3), size);
222 __glXReadPixelReply( Display *dpy, struct glx_context * gc, unsigned max_dim,
223 GLint width, GLint height, GLint depth, GLenum format, GLenum type,
224 void * dest, GLboolean dimensions_in_reply )
226 xGLXSingleReply reply;
229 (void) _XReply(dpy, (xReply *) & reply, 0, False);
231 if ( dimensions_in_reply ) {
236 if ((height == 0) || (max_dim < 2)) { height = 1; }
237 if ((depth == 0) || (max_dim < 3)) { depth = 1; }
240 size = reply.length * 4;
242 void * buf = Xmalloc( size );
245 _XEatData(dpy, size);
246 __glXSetError(gc, GL_OUT_OF_MEMORY);
249 const GLint extra = 4 - (size & 3);
251 _XRead(dpy, buf, size);
253 _XEatData(dpy, extra);
256 __glEmptyImage(gc, 3, width, height, depth, format, type,
263 #define X_GLXSingle 0
265 NOINLINE FASTCALL GLubyte *
266 __glXSetupSingleRequest( struct glx_context * gc, GLint sop, GLint cmdlen )
269 Display * const dpy = gc->currentDpy;
271 (void) __glXFlushRenderBuffer(gc, gc->pc);
273 GetReqExtra(GLXSingle, cmdlen, req);
274 req->reqType = gc->majorOpcode;
275 req->contextTag = gc->currentContextTag;
277 return (GLubyte *)(req) + sz_xGLXSingleReq;
280 NOINLINE FASTCALL GLubyte *
281 __glXSetupVendorRequest( struct glx_context * gc, GLint code, GLint vop, GLint cmdlen )
283 xGLXVendorPrivateReq * req;
284 Display * const dpy = gc->currentDpy;
286 (void) __glXFlushRenderBuffer(gc, gc->pc);
288 GetReqExtra(GLXVendorPrivate, cmdlen, req);
289 req->reqType = gc->majorOpcode;
291 req->vendorCode = vop;
292 req->contextTag = gc->currentContextTag;
293 return (GLubyte *)(req) + sz_xGLXVendorPrivateReq;
296 const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 };
298 #define zero (__glXDefaultPixelStore+0)
299 #define one (__glXDefaultPixelStore+8)
300 #define default_pixel_store_1D (__glXDefaultPixelStore+4)
301 #define default_pixel_store_1D_size 20
302 #define default_pixel_store_2D (__glXDefaultPixelStore+4)
303 #define default_pixel_store_2D_size 20
304 #define default_pixel_store_3D (__glXDefaultPixelStore+0)
305 #define default_pixel_store_3D_size 36
306 #define default_pixel_store_4D (__glXDefaultPixelStore+0)
307 #define default_pixel_store_4D_size 36
310 for size
in self
.generic_sizes
:
311 self
.print_generic_function(size
)
315 def printBody(self
, api
):
317 self
.pixel_stubs
= {}
320 for func
in api
.functionIterateGlx():
321 if func
.client_handcode
: continue
323 # If the function is a pixel function with a certain
324 # GLX protocol signature, create a fake stub function
325 # for it. For example, create a single stub function
326 # that is used to implement both glTexImage1D and
329 if func
.glx_rop
!= 0:
331 for image
in func
.get_images():
332 if image
.img_pad_dimensions
:
338 [h
, n
] = hash_pixel_function(func
)
341 self
.pixel_stubs
[ func
.name
] = n
342 if h
not in generated_stubs
:
343 generated_stubs
.append(h
)
345 fake_func
= glx_pixel_function_stub( func
, n
)
346 self
.printFunction(fake_func
, fake_func
.name
)
349 self
.printFunction(func
, func
.name
)
350 if func
.glx_sop
and func
.glx_vendorpriv
:
351 self
.printFunction(func
, func
.glx_vendorpriv_names
[0])
356 def printFunction(self
, func
, name
):
358 if func
.glx_rop
== ~
0:
359 print 'static %s' % (func
.return_type
)
360 print '%s( unsigned opcode, unsigned dim, %s )' % (func
.name
, func
.get_parameter_string())
363 if func
.has_different_protocol(name
):
364 if func
.return_type
== "void":
367 ret_string
= "return "
369 func_name
= func
.static_glx_name(name
)
370 print '#define %s %d' % (func
.opcode_vendor_name(name
), func
.glx_vendorpriv
)
371 print '%s gl%s(%s)' % (func
.return_type
, func_name
, func
.get_parameter_string())
373 print ' struct glx_context * const gc = __glXGetCurrentContext();'
375 print '#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)'
376 print ' if (gc->isDirect) {'
377 print ' %sGET_DISPATCH()->%s(%s);' % (ret_string
, func
.name
, func
.get_called_parameter_string())
384 print '#define %s %d' % (func
.opcode_name(), func
.opcode_value())
386 print '%s __indirect_gl%s(%s)' % (func
.return_type
, name
, func
.get_parameter_string())
390 if func
.glx_rop
!= 0 or func
.vectorequiv
!= None:
392 self
.printPixelFunction(func
)
394 self
.printRenderFunction(func
)
395 elif func
.glx_sop
!= 0 or func
.glx_vendorpriv
!= 0:
396 self
.printSingleFunction(func
, name
)
399 print "/* Missing GLX protocol for %s. */" % (name
)
405 def print_generic_function(self
, n
):
407 print """static FASTCALL NOINLINE void
408 generic_%u_byte( GLint rop, const void * ptr )
410 struct glx_context * const gc = __glXGetCurrentContext();
411 const GLuint cmdlen = %u;
413 emit_header(gc->pc, rop, cmdlen);
414 (void) memcpy((void *)(gc->pc + 4), ptr, %u);
416 if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }
418 """ % (n
, size
+ 4, size
)
422 def common_emit_one_arg(self
, p
, pc
, adjust
, extra_offset
):
426 src_ptr
= "&" + p
.name
429 print '(void) memset((void *)(%s + %u), 0, %s);' \
430 % (pc
, p
.offset
+ adjust
, p
.size_string() )
431 elif not extra_offset
:
432 print '(void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
433 % (pc
, p
.offset
+ adjust
, src_ptr
, p
.size_string() )
435 print '(void) memcpy((void *)(%s + %u + %s), (void *)(%s), %s);' \
436 % (pc
, p
.offset
+ adjust
, extra_offset
, src_ptr
, p
.size_string() )
438 def common_emit_args(self
, f
, pc
, adjust
, skip_vla
):
441 for p
in f
.parameterIterateGlxSend( not skip_vla
):
442 if p
.name
!= f
.img_reset
:
443 self
.common_emit_one_arg(p
, pc
, adjust
, extra_offset
)
445 if p
.is_variable_length():
446 temp
= p
.size_string()
448 extra_offset
+= " + %s" % (temp
)
455 def pixel_emit_args(self
, f
, pc
, large
):
456 """Emit the arguments for a pixel function. This differs from
457 common_emit_args in that pixel functions may require padding
458 be inserted (i.e., for the missing width field for
459 TexImage1D), and they may also require a 'NULL image' flag
460 be inserted before the image data."""
467 for param
in f
.parameterIterateGlxSend():
468 if not param
.is_image():
469 self
.common_emit_one_arg(param
, pc
, adjust
, None)
471 if f
.pad_after(param
):
472 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
+ param
.size()) + adjust
)
475 [dim
, width
, height
, depth
, extent
] = param
.get_dimensions()
482 print '(void) memset((void *)(%s + %u), 0, %s);' \
483 % (pc
, (param
.offset
- 4) + adjust
, param
.size_string() )
485 if param
.img_null_flag
:
487 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
- 4) + adjust
)
489 print '(void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (pc
, (param
.offset
- 4) + adjust
, param
.name
)
492 pixHeaderPtr
= "%s + %u" % (pc
, adjust
)
493 pcPtr
= "%s + %u" % (pc
, param
.offset
+ adjust
)
496 if param
.img_send_null
:
497 condition
= '(compsize > 0) && (%s != NULL)' % (param
.name
)
499 condition
= 'compsize > 0'
501 print 'if (%s) {' % (condition
)
502 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
)
504 print ' (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (pixHeaderPtr
, dim
, dim
)
507 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
)
512 def large_emit_begin(self
, f
, op_name
= None):
514 op_name
= f
.opcode_real_name()
516 print 'const GLint op = %s;' % (op_name
)
517 print 'const GLuint cmdlenLarge = cmdlen + 4;'
518 print 'GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);'
519 print '(void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);'
520 print '(void) memcpy((void *)(pc + 4), (void *)(&op), 4);'
524 def common_func_print_just_start(self
, f
, name
):
525 print ' struct glx_context * const gc = __glXGetCurrentContext();'
527 # The only reason that single and vendor private commands need
528 # a variable called 'dpy' is becuase they use the SyncHandle
529 # macro. For whatever brain-dead reason, that macro is hard-
530 # coded to use a variable called 'dpy' instead of taking a
533 # FIXME Simplify the logic related to skip_condition and
534 # FIXME condition_list in this function. Basically, remove
535 # FIXME skip_condition, and just append the "dpy != NULL" type
536 # FIXME condition to condition_list from the start. The only
537 # FIXME reason it's done in this confusing way now is to
538 # FIXME minimize the diffs in the generated code.
541 for p
in f
.parameterIterateOutputs():
542 if p
.is_image() and (p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP"):
543 print ' const __GLXattribute * const state = gc->client_state_private;'
546 print ' Display * const dpy = gc->currentDpy;'
547 skip_condition
= "dpy != NULL"
549 skip_condition
= "gc->currentDpy != NULL"
551 skip_condition
= None
554 if f
.return_type
!= 'void':
555 print ' %s retval = (%s) 0;' % (f
.return_type
, f
.return_type
)
558 if name
!= None and name
not in f
.glx_vendorpriv_names
:
559 print '#ifndef USE_XCB'
560 self
.emit_packet_size_calculation(f
, 0)
561 if name
!= None and name
not in f
.glx_vendorpriv_names
:
565 for p
in f
.parameterIterateCounters():
566 condition_list
.append( "%s >= 0" % (p
.name
) )
567 # 'counter' parameters cannot be negative
568 print " if (%s < 0) {" % p
.name
569 print " __glXSetError(gc, GL_INVALID_VALUE);"
570 if f
.return_type
!= 'void':
577 condition_list
.append( skip_condition
)
579 if len( condition_list
) > 0:
580 if len( condition_list
) > 1:
581 skip_condition
= "(%s)" % (string
.join( condition_list
, ") && (" ))
583 skip_condition
= "%s" % (condition_list
.pop(0))
585 print ' if (__builtin_expect(%s, 1)) {' % (skip_condition
)
591 def printSingleFunction(self
, f
, name
):
592 self
.common_func_print_just_start(f
, name
)
595 print ' printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
597 if name
not in f
.glx_vendorpriv_names
:
600 print '#ifdef USE_XCB'
602 print ' printf("\\tUsing XCB.\\n");'
603 print ' xcb_connection_t *c = XGetXCBConnection(dpy);'
604 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
605 xcb_name
= 'xcb_glx%s' % convertStringForXCB(name
)
610 for p
in f
.parameterIterator():
615 if p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP":
616 extra_iparams
.append("state->storePack.swapEndian")
618 extra_iparams
.append("0")
620 # Hardcode this in. lsb_first param (apparently always GL_FALSE)
621 # also present in GetPolygonStipple, but taken care of above.
622 if xcb_name
== "xcb_glx_read_pixels":
623 extra_iparams
.append("0")
625 iparams
.append(p
.name
)
628 xcb_request
= '%s(%s)' % (xcb_name
, ", ".join(["c", "gc->currentContextTag"] + iparams
+ extra_iparams
))
631 print ' %s_reply_t *reply = %s_reply(c, %s, NULL);' % (xcb_name
, xcb_name
, xcb_request
)
632 if output
and f
.reply_always_array
:
633 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
635 elif output
and not f
.reply_always_array
:
636 if not output
.is_image():
637 print ' if (%s_data_length(reply) == 0)' % (xcb_name
)
638 print ' (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output
.name
)
640 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
643 if f
.return_type
!= 'void':
644 print ' retval = reply->ret_val;'
645 print ' free(reply);'
647 print ' ' + xcb_request
+ ';'
649 # End of XCB specific.
652 if f
.parameters
!= []:
653 pc_decl
= "GLubyte const * pc ="
657 if name
in f
.glx_vendorpriv_names
:
658 print ' %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl
, f
.opcode_real_name(), f
.opcode_vendor_name(name
))
660 print ' %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl
, f
.opcode_name())
662 self
.common_emit_args(f
, "pc", 0, 0)
664 images
= f
.get_images()
668 o
= f
.command_fixed_length() - 4
669 print ' *(int32_t *)(pc + %u) = 0;' % (o
)
670 if img
.img_format
!= "GL_COLOR_INDEX" or img
.img_type
!= "GL_BITMAP":
671 print ' * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o
)
674 print ' * (int8_t *)(pc + %u) = %s;' % (o
+ 1, f
.img_reset
)
679 if f
.return_type
!= 'void':
680 return_name
= " retval"
681 return_str
= " retval = (%s)" % (f
.return_type
)
683 return_str
= " (void)"
687 for p
in f
.parameterIterateOutputs():
689 [dim
, w
, h
, d
, junk
] = p
.get_dimensions()
690 if f
.dimensions_in_reply
:
691 print " __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim
, p
.img_format
, p
.img_type
, p
.name
)
693 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
)
697 if f
.reply_always_array
:
702 # gl_parameter.size() returns the size
703 # of the entire data item. If the
704 # item is a fixed-size array, this is
705 # the size of the whole array. This
706 # is not what __glXReadReply wants. It
707 # wants the size of a single data
708 # element in the reply packet.
709 # Dividing by the array size (1 for
710 # non-arrays) gives us this.
712 s
= p
.size() / p
.get_element_count()
713 print " %s __glXReadReply(dpy, %s, %s, %s);" % (return_str
, s
, p
.name
, aa
)
717 # If a reply wasn't read to fill an output parameter,
718 # read a NULL reply to get the return value.
721 print " %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str
)
725 # Only emit the extra glFinish call for functions
726 # that don't already require a reply from the server.
727 print ' __indirect_glFinish();'
730 print ' printf( "Exit %%s.\\n", "gl%s" );' % (name
)
733 print ' UnlockDisplay(dpy); SyncHandle();'
735 if name
not in f
.glx_vendorpriv_names
:
736 print '#endif /* USE_XCB */'
739 print ' return%s;' % (return_name
)
743 def printPixelFunction(self
, f
):
744 if self
.pixel_stubs
.has_key( f
.name
):
745 # Normally gl_function::get_parameter_string could be
746 # used. However, this call needs to have the missing
747 # dimensions (e.g., a fake height value for
748 # glTexImage1D) added in.
751 for param
in f
.parameterIterateGlxSend():
755 p_string
+= ", " + param
.name
758 [dim
, junk
, junk
, junk
, junk
] = param
.get_dimensions()
760 if f
.pad_after(param
):
763 print ' %s(%s, %u%s );' % (self
.pixel_stubs
[f
.name
] , f
.opcode_name(), dim
, p_string
)
767 if self
.common_func_print_just_start(f
, None):
774 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
775 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
776 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
782 opcode
= f
.opcode_real_name()
784 print 'emit_header(gc->pc, %s, cmdlen);' % (opcode
)
786 self
.pixel_emit_args( f
, "gc->pc", 0 )
787 print 'gc->pc += cmdlen;'
788 print 'if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
794 self
.large_emit_begin(f
, opcode
)
795 self
.pixel_emit_args(f
, "pc", 1)
799 if trailer
: print trailer
803 def printRenderFunction(self
, f
):
804 # There is a class of GL functions that take a single pointer
805 # as a parameter. This pointer points to a fixed-size chunk
806 # of data, and the protocol for this functions is very
807 # regular. Since they are so regular and there are so many
808 # of them, special case them with generic functions. On
809 # x86, this saves about 26KB in the libGL.so binary.
811 if f
.variable_length_parameter() == None and len(f
.parameters
) == 1:
814 cmdlen
= f
.command_fixed_length()
815 if cmdlen
in self
.generic_sizes
:
816 print ' generic_%u_byte( %s, %s );' % (cmdlen
, f
.opcode_real_name(), p
.name
)
819 if self
.common_func_print_just_start(f
, None):
825 print 'printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
828 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
829 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
830 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
833 print 'emit_header(gc->pc, %s, cmdlen);' % (f
.opcode_real_name())
835 self
.common_emit_args(f
, "gc->pc", 4, 0)
836 print 'gc->pc += cmdlen;'
837 print 'if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
843 self
.large_emit_begin(f
)
844 self
.common_emit_args(f
, "pc", 8, 1)
846 p
= f
.variable_length_parameter()
847 print ' __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (p
.offset
+ 8, p
.name
, p
.size_string())
851 print '__indirect_glFinish();'
852 print 'printf( "Exit %%s.\\n", "gl%s" );' % (f
.name
)
854 if trailer
: print trailer
858 class PrintGlxProtoInit_c(gl_XML
.gl_print_base
):
860 gl_XML
.gl_print_base
.__init
__(self
)
862 self
.name
= "glX_proto_send.py (from Mesa)"
863 self
.license
= license
.bsd_license_template
% ( \
864 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
865 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
869 def printRealHeader(self
):
871 * \\file indirect_init.c
872 * Initialize indirect rendering dispatch table.
874 * \\author Kevin E. Martin <kevin@precisioninsight.com>
875 * \\author Brian Paul <brian@precisioninsight.com>
876 * \\author Ian Romanick <idr@us.ibm.com>
879 #include "indirect_init.h"
880 #include "indirect.h"
885 * No-op function used to initialize functions that have no GLX protocol
888 static int NoOp(void)
894 * Create and initialize a new GL dispatch table. The table is initialized
895 * with GLX indirect rendering protocol functions.
897 struct _glapi_table * __glXNewIndirectAPI( void )
899 struct _glapi_table *glAPI;
902 entries = _glapi_get_dispatch_table_size();
903 glAPI = (struct _glapi_table *) Xmalloc(entries * sizeof(void *));
905 /* first, set all entries to point to no-op functions */
908 void **dispatch = (void **) glAPI;
909 for (i = 0; i < entries; i++) {
910 dispatch[i] = (void *) NoOp;
914 /* now, initialize the entries we understand */"""
916 def printRealFooter(self
):
924 def printBody(self
, api
):
925 for [name
, number
] in api
.categoryIterate():
927 preamble
= '\n /* %3u. %s */\n\n' % (int(number
), name
)
929 preamble
= '\n /* %s */\n\n' % (name
)
931 for func
in api
.functionIterateByCategory(name
):
932 if func
.client_supported_for_indirect():
933 print '%s glAPI->%s = __indirect_gl%s;' % (preamble
, func
.name
, func
.name
)
939 class PrintGlxProtoInit_h(gl_XML
.gl_print_base
):
941 gl_XML
.gl_print_base
.__init
__(self
)
943 self
.name
= "glX_proto_send.py (from Mesa)"
944 self
.license
= license
.bsd_license_template
% ( \
945 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
946 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
947 self
.header_tag
= "_INDIRECT_H_"
949 self
.last_category
= ""
953 def printRealHeader(self
):
956 * Prototypes for indirect rendering functions.
958 * \\author Kevin E. Martin <kevin@precisioninsight.com>
959 * \\author Ian Romanick <idr@us.ibm.com>
962 self
.printVisibility( "HIDDEN", "hidden" )
967 #include "glxclient.h"
969 extern HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
970 void * dest, GLboolean reply_is_always_array );
972 extern HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
973 struct glx_context * gc, unsigned max_dim, GLint width, GLint height,
974 GLint depth, GLenum format, GLenum type, void * dest,
975 GLboolean dimensions_in_reply );
977 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
978 struct glx_context * gc, GLint sop, GLint cmdlen );
980 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
981 struct glx_context * gc, GLint code, GLint vop, GLint cmdlen );
985 def printBody(self
, api
):
986 for func
in api
.functionIterateGlx():
987 params
= func
.get_parameter_string()
989 print 'extern HIDDEN %s __indirect_gl%s(%s);' % (func
.return_type
, func
.name
, params
)
991 for n
in func
.entry_points
:
992 if func
.has_different_protocol(n
):
993 asdf
= func
.static_glx_name(n
)
994 if asdf
not in func
.static_entry_points
:
995 print 'extern HIDDEN %s gl%s(%s);' % (func
.return_type
, asdf
, params
)
996 # give it a easy-to-remember name
997 if func
.client_handcode
:
998 print '#define gl_dispatch_stub_%s gl%s' % (n
, asdf
)
1000 print 'GLAPI %s GLAPIENTRY gl%s(%s);' % (func
.return_type
, asdf
, params
)
1007 print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys
.argv
[0]
1008 print " -m output_mode Output mode can be one of 'proto', 'init_c' or 'init_h'."
1009 print " -d Enable extra debug information in the generated code."
1013 if __name__
== '__main__':
1014 file_name
= "gl_API.xml"
1017 (args
, trail
) = getopt
.getopt(sys
.argv
[1:], "f:m:d")
1023 for (arg
,val
) in args
:
1032 printer
= PrintGlxProtoStubs()
1033 elif mode
== "init_c":
1034 printer
= PrintGlxProtoInit_c()
1035 elif mode
== "init_h":
1036 printer
= PrintGlxProtoInit_h()
1041 printer
.debug
= debug
1042 api
= gl_XML
.parse_GL_API( file_name
, glX_XML
.glx_item_factory() )
1044 printer
.Print( api
)