1419a7cc1bc44444754dabf174ee652fefc19027
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 <GL/glxproto.h>'
171 print '#include <X11/Xlib-xcb.h>'
172 print '#include <xcb/xcb.h>'
173 print '#include <xcb/glx.h>'
176 print '#define __GLX_PAD(n) (((n) + 3) & ~3)'
181 print '#ifndef __GNUC__'
182 print '# define __builtin_expect(x, y) x'
185 print '/* If the size and opcode values are known at compile-time, this will, on'
186 print ' * x86 at least, emit them with a single instruction.'
188 print '#define emit_header(dest, op, size) \\'
189 print ' do { union { short s[2]; int i; } temp; \\'
190 print ' temp.s[0] = (size); temp.s[1] = (op); \\'
191 print ' *((int *)(dest)) = temp.i; } while(0)'
193 print """NOINLINE CARD32
194 __glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array )
196 xGLXSingleReply reply;
198 (void) _XReply(dpy, (xReply *) & reply, 0, False);
200 if ((reply.length > 0) || reply_is_always_array) {
201 const GLint bytes = (reply_is_always_array)
202 ? (4 * reply.length) : (reply.size * size);
203 const GLint extra = 4 - (bytes & 3);
205 _XRead(dpy, dest, bytes);
207 _XEatData(dpy, extra);
211 (void) memcpy( dest, &(reply.pad3), size);
219 __glXReadPixelReply( Display *dpy, struct glx_context * gc, unsigned max_dim,
220 GLint width, GLint height, GLint depth, GLenum format, GLenum type,
221 void * dest, GLboolean dimensions_in_reply )
223 xGLXSingleReply reply;
226 (void) _XReply(dpy, (xReply *) & reply, 0, False);
228 if ( dimensions_in_reply ) {
233 if ((height == 0) || (max_dim < 2)) { height = 1; }
234 if ((depth == 0) || (max_dim < 3)) { depth = 1; }
237 size = reply.length * 4;
239 void * buf = malloc( size );
242 _XEatData(dpy, size);
243 __glXSetError(gc, GL_OUT_OF_MEMORY);
246 const GLint extra = 4 - (size & 3);
248 _XRead(dpy, buf, size);
250 _XEatData(dpy, extra);
253 __glEmptyImage(gc, 3, width, height, depth, format, type,
260 #define X_GLXSingle 0
262 NOINLINE FASTCALL GLubyte *
263 __glXSetupSingleRequest( struct glx_context * gc, GLint sop, GLint cmdlen )
266 Display * const dpy = gc->currentDpy;
268 (void) __glXFlushRenderBuffer(gc, gc->pc);
270 GetReqExtra(GLXSingle, cmdlen, req);
271 req->reqType = gc->majorOpcode;
272 req->contextTag = gc->currentContextTag;
274 return (GLubyte *)(req) + sz_xGLXSingleReq;
277 NOINLINE FASTCALL GLubyte *
278 __glXSetupVendorRequest( struct glx_context * gc, GLint code, GLint vop, GLint cmdlen )
280 xGLXVendorPrivateReq * req;
281 Display * const dpy = gc->currentDpy;
283 (void) __glXFlushRenderBuffer(gc, gc->pc);
285 GetReqExtra(GLXVendorPrivate, cmdlen, req);
286 req->reqType = gc->majorOpcode;
288 req->vendorCode = vop;
289 req->contextTag = gc->currentContextTag;
290 return (GLubyte *)(req) + sz_xGLXVendorPrivateReq;
293 const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 };
295 #define zero (__glXDefaultPixelStore+0)
296 #define one (__glXDefaultPixelStore+8)
297 #define default_pixel_store_1D (__glXDefaultPixelStore+4)
298 #define default_pixel_store_1D_size 20
299 #define default_pixel_store_2D (__glXDefaultPixelStore+4)
300 #define default_pixel_store_2D_size 20
301 #define default_pixel_store_3D (__glXDefaultPixelStore+0)
302 #define default_pixel_store_3D_size 36
303 #define default_pixel_store_4D (__glXDefaultPixelStore+0)
304 #define default_pixel_store_4D_size 36
307 for size
in self
.generic_sizes
:
308 self
.print_generic_function(size
)
312 def printBody(self
, api
):
314 self
.pixel_stubs
= {}
317 for func
in api
.functionIterateGlx():
318 if func
.client_handcode
: continue
320 # If the function is a pixel function with a certain
321 # GLX protocol signature, create a fake stub function
322 # for it. For example, create a single stub function
323 # that is used to implement both glTexImage1D and
326 if func
.glx_rop
!= 0:
328 for image
in func
.get_images():
329 if image
.img_pad_dimensions
:
335 [h
, n
] = hash_pixel_function(func
)
338 self
.pixel_stubs
[ func
.name
] = n
339 if h
not in generated_stubs
:
340 generated_stubs
.append(h
)
342 fake_func
= glx_pixel_function_stub( func
, n
)
343 self
.printFunction(fake_func
, fake_func
.name
)
346 self
.printFunction(func
, func
.name
)
347 if func
.glx_sop
and func
.glx_vendorpriv
:
348 self
.printFunction(func
, func
.glx_vendorpriv_names
[0])
350 self
.printGetProcAddress(api
)
353 def printGetProcAddress(self
, api
):
355 for func
in api
.functionIterateGlx():
356 for n
in func
.entry_points
:
357 if func
.has_different_protocol(n
):
358 procs
[n
] = func
.static_glx_name(n
)
361 #ifdef GLX_SHARED_GLAPI
363 static const struct proc_pair
367 } proc_pairs[%d] = {""" % len(procs
)
370 for i
in xrange(len(names
)):
371 comma
= ',' if i
< len(names
) - 1 else ''
372 print ' { "%s", (_glapi_proc) gl%s }%s' % (names
[i
], procs
[names
[i
]], comma
)
376 __indirect_get_proc_compare(const void *key, const void *memb)
378 const struct proc_pair *pair = (const struct proc_pair *) memb;
379 return strcmp((const char *) key, pair->name);
383 __indirect_get_proc_address(const char *name)
385 const struct proc_pair *pair;
390 pair = (const struct proc_pair *) bsearch((const void *) name,
391 (const void *) proc_pairs, ARRAY_SIZE(proc_pairs), sizeof(proc_pairs[0]),
392 __indirect_get_proc_compare);
394 return (pair) ? pair->proc : NULL;
397 #endif /* GLX_SHARED_GLAPI */
402 def printFunction(self
, func
, name
):
404 if func
.glx_rop
== ~
0:
405 print 'static %s' % (func
.return_type
)
406 print '%s( unsigned opcode, unsigned dim, %s )' % (func
.name
, func
.get_parameter_string())
409 if func
.has_different_protocol(name
):
410 if func
.return_type
== "void":
413 ret_string
= "return "
415 func_name
= func
.static_glx_name(name
)
416 print '#define %s %d' % (func
.opcode_vendor_name(name
), func
.glx_vendorpriv
)
417 print '%s gl%s(%s)' % (func
.return_type
, func_name
, func
.get_parameter_string())
419 print ' struct glx_context * const gc = __glXGetCurrentContext();'
421 print '#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)'
422 print ' if (gc->isDirect) {'
423 print ' const _glapi_proc *const disp_table = (_glapi_proc *)GET_DISPATCH();'
424 print ' PFNGL%sPROC p =' % (name
.upper())
425 print ' (PFNGL%sPROC) disp_table[%d];' % (name
.upper(), func
.offset
)
426 print ' %sp(%s);' % (ret_string
, 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
)
682 if output
.is_image():
683 [dim
, w
, h
, d
, junk
] = output
.get_dimensions()
684 if f
.dimensions_in_reply
:
691 print ' if (%s == 0) { %s = 1; }' % (h
, h
)
695 print ' if (%s == 0) { %s = 1; }' % (d
, d
)
697 print ' __glEmptyImage(gc, 3, %s, %s, %s, %s, %s, %s_data(reply), %s);' % (w
, h
, d
, output
.img_format
, output
.img_type
, xcb_name
, output
.name
)
699 if f
.reply_always_array
:
700 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
702 print ' /* the XXX_data_length() xcb function name is misleading, it returns the number */'
703 print ' /* of elements, not the length of the data part. A single element is embedded. */'
704 print ' if (%s_data_length(reply) == 1)' % (xcb_name
)
705 print ' (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output
.name
)
707 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
709 if f
.return_type
!= 'void':
710 print ' retval = reply->ret_val;'
711 print ' free(reply);'
713 print ' ' + xcb_request
+ ';'
715 # End of XCB specific.
718 if f
.parameters
!= []:
719 pc_decl
= "GLubyte const * pc ="
723 if name
in f
.glx_vendorpriv_names
:
724 print ' %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl
, f
.opcode_real_name(), f
.opcode_vendor_name(name
))
726 print ' %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl
, f
.opcode_name())
728 self
.common_emit_args(f
, "pc", 0, 0)
730 images
= f
.get_images()
734 o
= f
.command_fixed_length() - 4
735 print ' *(int32_t *)(pc + %u) = 0;' % (o
)
736 if img
.img_format
!= "GL_COLOR_INDEX" or img
.img_type
!= "GL_BITMAP":
737 print ' * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o
)
740 print ' * (int8_t *)(pc + %u) = %s;' % (o
+ 1, f
.img_reset
)
745 if f
.return_type
!= 'void':
746 return_name
= " retval"
747 return_str
= " retval = (%s)" % (f
.return_type
)
749 return_str
= " (void)"
753 for p
in f
.parameterIterateOutputs():
755 [dim
, w
, h
, d
, junk
] = p
.get_dimensions()
756 if f
.dimensions_in_reply
:
757 print " __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim
, p
.img_format
, p
.img_type
, p
.name
)
759 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
)
763 if f
.reply_always_array
:
768 # gl_parameter.size() returns the size
769 # of the entire data item. If the
770 # item is a fixed-size array, this is
771 # the size of the whole array. This
772 # is not what __glXReadReply wants. It
773 # wants the size of a single data
774 # element in the reply packet.
775 # Dividing by the array size (1 for
776 # non-arrays) gives us this.
778 s
= p
.size() / p
.get_element_count()
779 print " %s __glXReadReply(dpy, %s, %s, %s);" % (return_str
, s
, p
.name
, aa
)
783 # If a reply wasn't read to fill an output parameter,
784 # read a NULL reply to get the return value.
787 print " %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str
)
791 # Only emit the extra glFinish call for functions
792 # that don't already require a reply from the server.
793 print ' __indirect_glFinish();'
796 print ' printf( "Exit %%s.\\n", "gl%s" );' % (name
)
799 print ' UnlockDisplay(dpy); SyncHandle();'
801 if name
not in f
.glx_vendorpriv_names
:
802 print '#endif /* USE_XCB */'
805 print ' return%s;' % (return_name
)
809 def printPixelFunction(self
, f
):
810 if self
.pixel_stubs
.has_key( f
.name
):
811 # Normally gl_function::get_parameter_string could be
812 # used. However, this call needs to have the missing
813 # dimensions (e.g., a fake height value for
814 # glTexImage1D) added in.
817 for param
in f
.parameterIterateGlxSend():
821 p_string
+= ", " + param
.name
824 [dim
, junk
, junk
, junk
, junk
] = param
.get_dimensions()
826 if f
.pad_after(param
):
829 print ' %s(%s, %u%s );' % (self
.pixel_stubs
[f
.name
] , f
.opcode_name(), dim
, p_string
)
833 if self
.common_func_print_just_start(f
, None):
840 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
841 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
842 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
848 opcode
= f
.opcode_real_name()
850 print 'emit_header(gc->pc, %s, cmdlen);' % (opcode
)
852 self
.pixel_emit_args( f
, "gc->pc", 0 )
853 print 'gc->pc += cmdlen;'
854 print 'if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
860 self
.large_emit_begin(f
, opcode
)
861 self
.pixel_emit_args(f
, "pc", 1)
865 if trailer
: print trailer
869 def printRenderFunction(self
, f
):
870 # There is a class of GL functions that take a single pointer
871 # as a parameter. This pointer points to a fixed-size chunk
872 # of data, and the protocol for this functions is very
873 # regular. Since they are so regular and there are so many
874 # of them, special case them with generic functions. On
875 # x86, this saves about 26KB in the libGL.so binary.
877 if f
.variable_length_parameter() == None and len(f
.parameters
) == 1:
880 cmdlen
= f
.command_fixed_length()
881 if cmdlen
in self
.generic_sizes
:
882 print ' generic_%u_byte( %s, %s );' % (cmdlen
, f
.opcode_real_name(), p
.name
)
885 if self
.common_func_print_just_start(f
, None):
891 print 'printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
894 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
895 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
896 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
899 print 'emit_header(gc->pc, %s, cmdlen);' % (f
.opcode_real_name())
901 self
.common_emit_args(f
, "gc->pc", 4, 0)
902 print 'gc->pc += cmdlen;'
903 print 'if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
909 self
.large_emit_begin(f
)
910 self
.common_emit_args(f
, "pc", 8, 1)
912 p
= f
.variable_length_parameter()
913 print ' __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (p
.offset
+ 8, p
.name
, p
.size_string())
917 print '__indirect_glFinish();'
918 print 'printf( "Exit %%s.\\n", "gl%s" );' % (f
.name
)
920 if trailer
: print trailer
924 class PrintGlxProtoInit_c(gl_XML
.gl_print_base
):
926 gl_XML
.gl_print_base
.__init
__(self
)
928 self
.name
= "glX_proto_send.py (from Mesa)"
929 self
.license
= license
.bsd_license_template
% ( \
930 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
931 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
935 def printRealHeader(self
):
937 * \\file indirect_init.c
938 * Initialize indirect rendering dispatch table.
940 * \\author Kevin E. Martin <kevin@precisioninsight.com>
941 * \\author Brian Paul <brian@precisioninsight.com>
942 * \\author Ian Romanick <idr@us.ibm.com>
945 #include "indirect_init.h"
946 #include "indirect.h"
950 #ifndef GLX_USE_APPLEGL
953 * No-op function used to initialize functions that have no GLX protocol
956 static int NoOp(void)
962 * Create and initialize a new GL dispatch table. The table is initialized
963 * with GLX indirect rendering protocol functions.
965 struct _glapi_table * __glXNewIndirectAPI( void )
972 entries = _glapi_get_dispatch_table_size();
973 table = malloc(entries * sizeof(_glapi_proc));
977 /* first, set all entries to point to no-op functions */
978 for (i = 0; i < entries; i++) {
979 table[i] = (_glapi_proc) NoOp;
982 /* now, initialize the entries we understand */"""
984 def printRealFooter(self
):
986 return (struct _glapi_table *) table;
994 def printBody(self
, api
):
995 for [name
, number
] in api
.categoryIterate():
997 preamble
= '\n /* %3u. %s */\n' % (int(number
), name
)
999 preamble
= '\n /* %s */\n' % (name
)
1001 for func
in api
.functionIterateByCategory(name
):
1002 if func
.client_supported_for_indirect():
1008 print ' table[{offset}] = (_glapi_proc) __indirect_gl{name};'.format(name
= func
.name
, offset
= func
.offset
)
1010 print ' o = _glapi_get_proc_offset("gl{0}");'.format(func
.name
)
1011 print ' assert(o > 0);'
1012 print ' table[o] = (_glapi_proc) __indirect_gl{0};'.format(func
.name
)
1017 class PrintGlxProtoInit_h(gl_XML
.gl_print_base
):
1019 gl_XML
.gl_print_base
.__init
__(self
)
1021 self
.name
= "glX_proto_send.py (from Mesa)"
1022 self
.license
= license
.bsd_license_template
% ( \
1023 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
1024 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
1025 self
.header_tag
= "_INDIRECT_H_"
1027 self
.last_category
= ""
1031 def printRealHeader(self
):
1034 * Prototypes for indirect rendering functions.
1036 * \\author Kevin E. Martin <kevin@precisioninsight.com>
1037 * \\author Ian Romanick <idr@us.ibm.com>
1040 self
.printFastcall()
1041 self
.printNoinline()
1044 #include <X11/Xfuncproto.h>
1045 #include "glxclient.h"
1047 extern _X_HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
1048 void * dest, GLboolean reply_is_always_array );
1050 extern _X_HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
1051 struct glx_context * gc, unsigned max_dim, GLint width, GLint height,
1052 GLint depth, GLenum format, GLenum type, void * dest,
1053 GLboolean dimensions_in_reply );
1055 extern _X_HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
1056 struct glx_context * gc, GLint sop, GLint cmdlen );
1058 extern _X_HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
1059 struct glx_context * gc, GLint code, GLint vop, GLint cmdlen );
1063 def printBody(self
, api
):
1064 for func
in api
.functionIterateGlx():
1065 params
= func
.get_parameter_string()
1067 print 'extern _X_HIDDEN %s __indirect_gl%s(%s);' % (func
.return_type
, func
.name
, params
)
1069 for n
in func
.entry_points
:
1070 if func
.has_different_protocol(n
):
1071 asdf
= func
.static_glx_name(n
)
1072 if asdf
not in func
.static_entry_points
:
1073 print 'extern _X_HIDDEN %s gl%s(%s);' % (func
.return_type
, asdf
, params
)
1074 # give it a easy-to-remember name
1075 if func
.client_handcode
:
1076 print '#define gl_dispatch_stub_%s gl%s' % (n
, asdf
)
1078 print 'GLAPI %s GLAPIENTRY gl%s(%s);' % (func
.return_type
, asdf
, params
)
1083 print '#ifdef GLX_SHARED_GLAPI'
1084 print 'extern _X_HIDDEN void (*__indirect_get_proc_address(const char *name))(void);'
1089 print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys
.argv
[0]
1090 print " -m output_mode Output mode can be one of 'proto', 'init_c' or 'init_h'."
1091 print " -d Enable extra debug information in the generated code."
1095 if __name__
== '__main__':
1096 file_name
= "gl_API.xml"
1099 (args
, trail
) = getopt
.getopt(sys
.argv
[1:], "f:m:d")
1105 for (arg
,val
) in args
:
1114 printer
= PrintGlxProtoStubs()
1115 elif mode
== "init_c":
1116 printer
= PrintGlxProtoInit_c()
1117 elif mode
== "init_h":
1118 printer
= PrintGlxProtoInit_h()
1123 printer
.debug
= debug
1124 api
= gl_XML
.parse_GL_API( file_name
, glX_XML
.glx_item_factory() )
1126 printer
.Print( api
)