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])
353 self
.printGetProcAddress(api
)
356 def printGetProcAddress(self
, api
):
358 for func
in api
.functionIterateGlx():
359 for n
in func
.entry_points
:
360 if func
.has_different_protocol(n
):
361 procs
[n
] = func
.static_glx_name(n
)
364 #ifdef GLX_SHARED_GLAPI
366 static const struct proc_pair
370 } proc_pairs[%d] = {""" % len(procs
)
373 for i
in xrange(len(names
)):
374 comma
= ',' if i
< len(names
) - 1 else ''
375 print ' { "%s", (_glapi_proc) gl%s }%s' % (names
[i
], procs
[names
[i
]], comma
)
379 __indirect_get_proc_compare(const void *key, const void *memb)
381 const struct proc_pair *pair = (const struct proc_pair *) memb;
382 return strcmp((const char *) key, pair->name);
386 __indirect_get_proc_address(const char *name)
388 const struct proc_pair *pair;
393 pair = (const struct proc_pair *) bsearch((const void *) name,
394 (const void *) proc_pairs, ARRAY_SIZE(proc_pairs), sizeof(proc_pairs[0]),
395 __indirect_get_proc_compare);
397 return (pair) ? pair->proc : NULL;
400 #endif /* GLX_SHARED_GLAPI */
405 def printFunction(self
, func
, name
):
407 if func
.glx_rop
== ~
0:
408 print 'static %s' % (func
.return_type
)
409 print '%s( unsigned opcode, unsigned dim, %s )' % (func
.name
, func
.get_parameter_string())
412 if func
.has_different_protocol(name
):
413 if func
.return_type
== "void":
416 ret_string
= "return "
418 func_name
= func
.static_glx_name(name
)
419 print '#define %s %d' % (func
.opcode_vendor_name(name
), func
.glx_vendorpriv
)
420 print '%s gl%s(%s)' % (func
.return_type
, func_name
, func
.get_parameter_string())
422 print ' struct glx_context * const gc = __glXGetCurrentContext();'
424 print '#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)'
425 print ' if (gc->isDirect) {'
426 print ' %sGET_DISPATCH()->%s(%s);' % (ret_string
, func
.name
, func
.get_called_parameter_string())
433 print '#define %s %d' % (func
.opcode_name(), func
.opcode_value())
435 print '%s __indirect_gl%s(%s)' % (func
.return_type
, name
, func
.get_parameter_string())
439 if func
.glx_rop
!= 0 or func
.vectorequiv
!= None:
441 self
.printPixelFunction(func
)
443 self
.printRenderFunction(func
)
444 elif func
.glx_sop
!= 0 or func
.glx_vendorpriv
!= 0:
445 self
.printSingleFunction(func
, name
)
448 print "/* Missing GLX protocol for %s. */" % (name
)
454 def print_generic_function(self
, n
):
456 print """static FASTCALL NOINLINE void
457 generic_%u_byte( GLint rop, const void * ptr )
459 struct glx_context * const gc = __glXGetCurrentContext();
460 const GLuint cmdlen = %u;
462 emit_header(gc->pc, rop, cmdlen);
463 (void) memcpy((void *)(gc->pc + 4), ptr, %u);
465 if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }
467 """ % (n
, size
+ 4, size
)
471 def common_emit_one_arg(self
, p
, pc
, adjust
, extra_offset
):
475 src_ptr
= "&" + p
.name
478 print '(void) memset((void *)(%s + %u), 0, %s);' \
479 % (pc
, p
.offset
+ adjust
, p
.size_string() )
480 elif not extra_offset
:
481 print '(void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
482 % (pc
, p
.offset
+ adjust
, src_ptr
, p
.size_string() )
484 print '(void) memcpy((void *)(%s + %u + %s), (void *)(%s), %s);' \
485 % (pc
, p
.offset
+ adjust
, extra_offset
, src_ptr
, p
.size_string() )
487 def common_emit_args(self
, f
, pc
, adjust
, skip_vla
):
490 for p
in f
.parameterIterateGlxSend( not skip_vla
):
491 if p
.name
!= f
.img_reset
:
492 self
.common_emit_one_arg(p
, pc
, adjust
, extra_offset
)
494 if p
.is_variable_length():
495 temp
= p
.size_string()
497 extra_offset
+= " + %s" % (temp
)
504 def pixel_emit_args(self
, f
, pc
, large
):
505 """Emit the arguments for a pixel function. This differs from
506 common_emit_args in that pixel functions may require padding
507 be inserted (i.e., for the missing width field for
508 TexImage1D), and they may also require a 'NULL image' flag
509 be inserted before the image data."""
516 for param
in f
.parameterIterateGlxSend():
517 if not param
.is_image():
518 self
.common_emit_one_arg(param
, pc
, adjust
, None)
520 if f
.pad_after(param
):
521 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
+ param
.size()) + adjust
)
524 [dim
, width
, height
, depth
, extent
] = param
.get_dimensions()
531 print '(void) memset((void *)(%s + %u), 0, %s);' \
532 % (pc
, (param
.offset
- 4) + adjust
, param
.size_string() )
534 if param
.img_null_flag
:
536 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
- 4) + adjust
)
538 print '(void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (pc
, (param
.offset
- 4) + adjust
, param
.name
)
541 pixHeaderPtr
= "%s + %u" % (pc
, adjust
)
542 pcPtr
= "%s + %u" % (pc
, param
.offset
+ adjust
)
545 if param
.img_send_null
:
546 condition
= '(compsize > 0) && (%s != NULL)' % (param
.name
)
548 condition
= 'compsize > 0'
550 print 'if (%s) {' % (condition
)
551 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
)
553 print ' (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (pixHeaderPtr
, dim
, dim
)
556 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
)
561 def large_emit_begin(self
, f
, op_name
= None):
563 op_name
= f
.opcode_real_name()
565 print 'const GLint op = %s;' % (op_name
)
566 print 'const GLuint cmdlenLarge = cmdlen + 4;'
567 print 'GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);'
568 print '(void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);'
569 print '(void) memcpy((void *)(pc + 4), (void *)(&op), 4);'
573 def common_func_print_just_start(self
, f
, name
):
574 print ' struct glx_context * const gc = __glXGetCurrentContext();'
576 # The only reason that single and vendor private commands need
577 # a variable called 'dpy' is becuase they use the SyncHandle
578 # macro. For whatever brain-dead reason, that macro is hard-
579 # coded to use a variable called 'dpy' instead of taking a
582 # FIXME Simplify the logic related to skip_condition and
583 # FIXME condition_list in this function. Basically, remove
584 # FIXME skip_condition, and just append the "dpy != NULL" type
585 # FIXME condition to condition_list from the start. The only
586 # FIXME reason it's done in this confusing way now is to
587 # FIXME minimize the diffs in the generated code.
590 for p
in f
.parameterIterateOutputs():
591 if p
.is_image() and (p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP"):
592 print ' const __GLXattribute * const state = gc->client_state_private;'
595 print ' Display * const dpy = gc->currentDpy;'
596 skip_condition
= "dpy != NULL"
598 skip_condition
= "gc->currentDpy != NULL"
600 skip_condition
= None
603 if f
.return_type
!= 'void':
604 print ' %s retval = (%s) 0;' % (f
.return_type
, f
.return_type
)
607 if name
!= None and name
not in f
.glx_vendorpriv_names
:
608 print '#ifndef USE_XCB'
609 self
.emit_packet_size_calculation(f
, 0)
610 if name
!= None and name
not in f
.glx_vendorpriv_names
:
614 for p
in f
.parameterIterateCounters():
615 condition_list
.append( "%s >= 0" % (p
.name
) )
616 # 'counter' parameters cannot be negative
617 print " if (%s < 0) {" % p
.name
618 print " __glXSetError(gc, GL_INVALID_VALUE);"
619 if f
.return_type
!= 'void':
626 condition_list
.append( skip_condition
)
628 if len( condition_list
) > 0:
629 if len( condition_list
) > 1:
630 skip_condition
= "(%s)" % (string
.join( condition_list
, ") && (" ))
632 skip_condition
= "%s" % (condition_list
.pop(0))
634 print ' if (__builtin_expect(%s, 1)) {' % (skip_condition
)
640 def printSingleFunction(self
, f
, name
):
641 self
.common_func_print_just_start(f
, name
)
644 print ' printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
646 if name
not in f
.glx_vendorpriv_names
:
649 print '#ifdef USE_XCB'
651 print ' printf("\\tUsing XCB.\\n");'
652 print ' xcb_connection_t *c = XGetXCBConnection(dpy);'
653 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
654 xcb_name
= 'xcb_glx%s' % convertStringForXCB(name
)
659 for p
in f
.parameterIterator():
664 if p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP":
665 extra_iparams
.append("state->storePack.swapEndian")
667 extra_iparams
.append("0")
669 # Hardcode this in. lsb_first param (apparently always GL_FALSE)
670 # also present in GetPolygonStipple, but taken care of above.
671 if xcb_name
== "xcb_glx_read_pixels":
672 extra_iparams
.append("0")
674 iparams
.append(p
.name
)
677 xcb_request
= '%s(%s)' % (xcb_name
, ", ".join(["c", "gc->currentContextTag"] + iparams
+ extra_iparams
))
680 print ' %s_reply_t *reply = %s_reply(c, %s, NULL);' % (xcb_name
, xcb_name
, xcb_request
)
681 if output
and f
.reply_always_array
:
682 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
684 elif output
and not f
.reply_always_array
:
685 if not output
.is_image():
686 print ' if (%s_data_length(reply) == 0)' % (xcb_name
)
687 print ' (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output
.name
)
689 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
692 if f
.return_type
!= 'void':
693 print ' retval = reply->ret_val;'
694 print ' free(reply);'
696 print ' ' + xcb_request
+ ';'
698 # End of XCB specific.
701 if f
.parameters
!= []:
702 pc_decl
= "GLubyte const * pc ="
706 if name
in f
.glx_vendorpriv_names
:
707 print ' %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl
, f
.opcode_real_name(), f
.opcode_vendor_name(name
))
709 print ' %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl
, f
.opcode_name())
711 self
.common_emit_args(f
, "pc", 0, 0)
713 images
= f
.get_images()
717 o
= f
.command_fixed_length() - 4
718 print ' *(int32_t *)(pc + %u) = 0;' % (o
)
719 if img
.img_format
!= "GL_COLOR_INDEX" or img
.img_type
!= "GL_BITMAP":
720 print ' * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o
)
723 print ' * (int8_t *)(pc + %u) = %s;' % (o
+ 1, f
.img_reset
)
728 if f
.return_type
!= 'void':
729 return_name
= " retval"
730 return_str
= " retval = (%s)" % (f
.return_type
)
732 return_str
= " (void)"
736 for p
in f
.parameterIterateOutputs():
738 [dim
, w
, h
, d
, junk
] = p
.get_dimensions()
739 if f
.dimensions_in_reply
:
740 print " __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim
, p
.img_format
, p
.img_type
, p
.name
)
742 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
)
746 if f
.reply_always_array
:
751 # gl_parameter.size() returns the size
752 # of the entire data item. If the
753 # item is a fixed-size array, this is
754 # the size of the whole array. This
755 # is not what __glXReadReply wants. It
756 # wants the size of a single data
757 # element in the reply packet.
758 # Dividing by the array size (1 for
759 # non-arrays) gives us this.
761 s
= p
.size() / p
.get_element_count()
762 print " %s __glXReadReply(dpy, %s, %s, %s);" % (return_str
, s
, p
.name
, aa
)
766 # If a reply wasn't read to fill an output parameter,
767 # read a NULL reply to get the return value.
770 print " %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str
)
774 # Only emit the extra glFinish call for functions
775 # that don't already require a reply from the server.
776 print ' __indirect_glFinish();'
779 print ' printf( "Exit %%s.\\n", "gl%s" );' % (name
)
782 print ' UnlockDisplay(dpy); SyncHandle();'
784 if name
not in f
.glx_vendorpriv_names
:
785 print '#endif /* USE_XCB */'
788 print ' return%s;' % (return_name
)
792 def printPixelFunction(self
, f
):
793 if self
.pixel_stubs
.has_key( f
.name
):
794 # Normally gl_function::get_parameter_string could be
795 # used. However, this call needs to have the missing
796 # dimensions (e.g., a fake height value for
797 # glTexImage1D) added in.
800 for param
in f
.parameterIterateGlxSend():
804 p_string
+= ", " + param
.name
807 [dim
, junk
, junk
, junk
, junk
] = param
.get_dimensions()
809 if f
.pad_after(param
):
812 print ' %s(%s, %u%s );' % (self
.pixel_stubs
[f
.name
] , f
.opcode_name(), dim
, p_string
)
816 if self
.common_func_print_just_start(f
, None):
823 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
824 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
825 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
831 opcode
= f
.opcode_real_name()
833 print 'emit_header(gc->pc, %s, cmdlen);' % (opcode
)
835 self
.pixel_emit_args( f
, "gc->pc", 0 )
836 print 'gc->pc += cmdlen;'
837 print 'if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
843 self
.large_emit_begin(f
, opcode
)
844 self
.pixel_emit_args(f
, "pc", 1)
848 if trailer
: print trailer
852 def printRenderFunction(self
, f
):
853 # There is a class of GL functions that take a single pointer
854 # as a parameter. This pointer points to a fixed-size chunk
855 # of data, and the protocol for this functions is very
856 # regular. Since they are so regular and there are so many
857 # of them, special case them with generic functions. On
858 # x86, this saves about 26KB in the libGL.so binary.
860 if f
.variable_length_parameter() == None and len(f
.parameters
) == 1:
863 cmdlen
= f
.command_fixed_length()
864 if cmdlen
in self
.generic_sizes
:
865 print ' generic_%u_byte( %s, %s );' % (cmdlen
, f
.opcode_real_name(), p
.name
)
868 if self
.common_func_print_just_start(f
, None):
874 print 'printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
877 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
878 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
879 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
882 print 'emit_header(gc->pc, %s, cmdlen);' % (f
.opcode_real_name())
884 self
.common_emit_args(f
, "gc->pc", 4, 0)
885 print 'gc->pc += cmdlen;'
886 print 'if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
892 self
.large_emit_begin(f
)
893 self
.common_emit_args(f
, "pc", 8, 1)
895 p
= f
.variable_length_parameter()
896 print ' __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (p
.offset
+ 8, p
.name
, p
.size_string())
900 print '__indirect_glFinish();'
901 print 'printf( "Exit %%s.\\n", "gl%s" );' % (f
.name
)
903 if trailer
: print trailer
907 class PrintGlxProtoInit_c(gl_XML
.gl_print_base
):
909 gl_XML
.gl_print_base
.__init
__(self
)
911 self
.name
= "glX_proto_send.py (from Mesa)"
912 self
.license
= license
.bsd_license_template
% ( \
913 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
914 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
918 def printRealHeader(self
):
920 * \\file indirect_init.c
921 * Initialize indirect rendering dispatch table.
923 * \\author Kevin E. Martin <kevin@precisioninsight.com>
924 * \\author Brian Paul <brian@precisioninsight.com>
925 * \\author Ian Romanick <idr@us.ibm.com>
928 #include "indirect_init.h"
929 #include "indirect.h"
934 * No-op function used to initialize functions that have no GLX protocol
937 static int NoOp(void)
943 * Create and initialize a new GL dispatch table. The table is initialized
944 * with GLX indirect rendering protocol functions.
946 struct _glapi_table * __glXNewIndirectAPI( void )
948 struct _glapi_table *glAPI;
951 entries = _glapi_get_dispatch_table_size();
952 glAPI = (struct _glapi_table *) Xmalloc(entries * sizeof(void *));
954 /* first, set all entries to point to no-op functions */
957 void **dispatch = (void **) glAPI;
958 for (i = 0; i < entries; i++) {
959 dispatch[i] = (void *) NoOp;
963 /* now, initialize the entries we understand */"""
965 def printRealFooter(self
):
973 def printBody(self
, api
):
974 for [name
, number
] in api
.categoryIterate():
976 preamble
= '\n /* %3u. %s */\n\n' % (int(number
), name
)
978 preamble
= '\n /* %s */\n\n' % (name
)
980 for func
in api
.functionIterateByCategory(name
):
981 if func
.client_supported_for_indirect():
982 print '%s glAPI->%s = __indirect_gl%s;' % (preamble
, func
.name
, func
.name
)
988 class PrintGlxProtoInit_h(gl_XML
.gl_print_base
):
990 gl_XML
.gl_print_base
.__init
__(self
)
992 self
.name
= "glX_proto_send.py (from Mesa)"
993 self
.license
= license
.bsd_license_template
% ( \
994 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
995 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
996 self
.header_tag
= "_INDIRECT_H_"
998 self
.last_category
= ""
1002 def printRealHeader(self
):
1005 * Prototypes for indirect rendering functions.
1007 * \\author Kevin E. Martin <kevin@precisioninsight.com>
1008 * \\author Ian Romanick <idr@us.ibm.com>
1011 self
.printVisibility( "HIDDEN", "hidden" )
1012 self
.printFastcall()
1013 self
.printNoinline()
1016 #include "glxclient.h"
1018 extern HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
1019 void * dest, GLboolean reply_is_always_array );
1021 extern HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
1022 struct glx_context * gc, unsigned max_dim, GLint width, GLint height,
1023 GLint depth, GLenum format, GLenum type, void * dest,
1024 GLboolean dimensions_in_reply );
1026 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
1027 struct glx_context * gc, GLint sop, GLint cmdlen );
1029 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
1030 struct glx_context * gc, GLint code, GLint vop, GLint cmdlen );
1034 def printBody(self
, api
):
1035 for func
in api
.functionIterateGlx():
1036 params
= func
.get_parameter_string()
1038 print 'extern HIDDEN %s __indirect_gl%s(%s);' % (func
.return_type
, func
.name
, params
)
1040 for n
in func
.entry_points
:
1041 if func
.has_different_protocol(n
):
1042 asdf
= func
.static_glx_name(n
)
1043 if asdf
not in func
.static_entry_points
:
1044 print 'extern HIDDEN %s gl%s(%s);' % (func
.return_type
, asdf
, params
)
1045 # give it a easy-to-remember name
1046 if func
.client_handcode
:
1047 print '#define gl_dispatch_stub_%s gl%s' % (n
, asdf
)
1049 print 'GLAPI %s GLAPIENTRY gl%s(%s);' % (func
.return_type
, asdf
, params
)
1054 print '#ifdef GLX_SHARED_GLAPI'
1055 print 'extern HIDDEN void (*__indirect_get_proc_address(const char *name))(void);'
1060 print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys
.argv
[0]
1061 print " -m output_mode Output mode can be one of 'proto', 'init_c' or 'init_h'."
1062 print " -d Enable extra debug information in the generated code."
1066 if __name__
== '__main__':
1067 file_name
= "gl_API.xml"
1070 (args
, trail
) = getopt
.getopt(sys
.argv
[1:], "f:m:d")
1076 for (arg
,val
) in args
:
1085 printer
= PrintGlxProtoStubs()
1086 elif mode
== "init_c":
1087 printer
= PrintGlxProtoInit_c()
1088 elif mode
== "init_h":
1089 printer
= PrintGlxProtoInit_h()
1094 printer
.debug
= debug
1095 api
= gl_XML
.parse_GL_API( file_name
, glX_XML
.glx_item_factory() )
1097 printer
.Print( api
)