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>
31 import sys
, getopt
, copy
33 def hash_pixel_function(func
):
34 """Generate a 'unique' key for a pixel function. The key is based on
35 the parameters written in the command packet. This includes any
36 padding that might be added for the original function and the 'NULL
39 [dim
, junk
, junk
, junk
, junk
] = func
.dimensions()
42 h
= "%uD%uD_" % (d
- 1, d
)
44 for p
in func
.parameterIterator(1, 1):
45 h
= "%s%u" % (h
, p
.size())
50 if func
.image
.img_null_flag
:
53 n
= func
.name
.replace("%uD" % (dim
), "")
54 n
= "__glx_%s_%uD%uD" % (n
, d
- 1, d
)
58 class glXPixelFunctionUtility(glX_XML
.glXFunction
):
59 """Dummy class used to generate pixel "utility" functions that are
60 shared by multiple dimension image functions. For example, these
61 objects are used to generate shared functions used to send GLX
62 protocol for TexImage1D and TexImage2D, TexSubImage1D and
63 TexSubImage2D, etc."""
65 def __init__(self
, func
, name
):
66 # The parameters to the utility function are the same as the
67 # parameters to the real function except for the added "pad"
71 self
.image
= copy
.copy(func
.image
)
72 self
.fn_parameters
= []
73 for p
in gl_XML
.glFunction
.parameterIterator(func
):
74 self
.fn_parameters
.append(p
)
76 pad_name
= func
.pad_after(p
)
80 self
.fn_parameters
.append(pad
)
83 if self
.image
.height
== None:
84 self
.image
.height
= "height"
86 if self
.image
.img_yoff
== None:
87 self
.image
.img_yoff
= "yoffset"
90 if self
.image
.extent
== None:
91 self
.image
.extent
= "extent"
93 if self
.image
.img_woff
== None:
94 self
.image
.img_woff
= "woffset"
97 self
.set_return_type( func
.fn_return_type
)
99 self
.can_be_large
= func
.can_be_large
100 self
.count_parameter_list
= func
.count_parameter_list
101 self
.counter
= func
.counter
102 self
.img_reset
= None
106 class PrintGlxProtoStubs(glX_XML
.GlxProto
):
108 glX_XML
.GlxProto
.__init
__(self
)
109 self
.last_category
= ""
110 self
.license
= license
.bsd_license_template
% ( "(C) Copyright IBM Corporation 2004, 2005", "IBM")
111 self
.generic_sizes
= [3, 4, 6, 8, 12, 16, 24, 32]
112 self
.pixel_stubs
= {}
116 def printRealHeader(self
):
118 print '#include <GL/gl.h>'
119 print '#include "indirect.h"'
120 print '#include "glxclient.h"'
121 print '#include "indirect_size.h"'
122 print '#include <GL/glxproto.h>'
123 print '#ifdef USE_XCB'
124 print '#include <X11/xcl.h>'
125 print '#include <X11/XCB/xcb.h>'
126 print '#include <X11/XCB/glx.h>'
127 print '#endif /* USE_XCB */'
130 print '#define __GLX_PAD(n) (((n) + 3) & ~3)'
135 print '#if !defined __GNUC__ || __GNUC__ < 3'
136 print '# define __builtin_expect(x, y) x'
139 print '/* If the size and opcode values are known at compile-time, this will, on'
140 print ' * x86 at least, emit them with a single instruction.'
142 print '#define emit_header(dest, op, size) \\'
143 print ' do { union { short s[2]; int i; } temp; \\'
144 print ' temp.s[0] = (size); temp.s[1] = (op); \\'
145 print ' *((int *)(dest)) = temp.i; } while(0)'
147 print """NOINLINE CARD32
148 __glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array )
150 xGLXSingleReply reply;
152 (void) _XReply(dpy, (xReply *) & reply, 0, False);
154 if ((reply.length > 0) || reply_is_always_array) {
155 const GLint bytes = (reply_is_always_array)
156 ? (4 * reply.length) : (reply.size * size);
157 const GLint extra = 4 - (bytes & 3);
159 _XRead(dpy, dest, bytes);
161 _XEatData(dpy, extra);
165 (void) memcpy( dest, &(reply.pad3), size);
173 __glXReadPixelReply( Display *dpy, __GLXcontext * gc, unsigned max_dim,
174 GLint width, GLint height, GLint depth, GLenum format, GLenum type,
175 void * dest, GLboolean dimensions_in_reply )
177 xGLXSingleReply reply;
180 (void) _XReply(dpy, (xReply *) & reply, 0, False);
182 if ( dimensions_in_reply ) {
187 if ((height == 0) || (max_dim < 2)) { height = 1; }
188 if ((depth == 0) || (max_dim < 3)) { depth = 1; }
191 size = reply.length * 4;
193 void * buf = Xmalloc( size );
196 _XEatData(dpy, size);
197 __glXSetError(gc, GL_OUT_OF_MEMORY);
200 const GLint extra = 4 - (size & 3);
202 _XRead(dpy, buf, size);
204 _XEatData(dpy, extra);
207 __glEmptyImage(gc, 3, width, height, depth, format, type,
214 #define X_GLXSingle 0
216 NOINLINE FASTCALL GLubyte *
217 __glXSetupSingleRequest( __GLXcontext * gc, GLint sop, GLint cmdlen )
220 Display * const dpy = gc->currentDpy;
222 (void) __glXFlushRenderBuffer(gc, gc->pc);
224 GetReqExtra(GLXSingle, cmdlen, req);
225 req->reqType = gc->majorOpcode;
226 req->contextTag = gc->currentContextTag;
228 return (GLubyte *)(req) + sz_xGLXSingleReq;
231 NOINLINE FASTCALL GLubyte *
232 __glXSetupVendorRequest( __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen )
234 xGLXVendorPrivateReq * req;
235 Display * const dpy = gc->currentDpy;
237 (void) __glXFlushRenderBuffer(gc, gc->pc);
239 GetReqExtra(GLXVendorPrivate, cmdlen, req);
240 req->reqType = gc->majorOpcode;
242 req->vendorCode = vop;
243 req->contextTag = gc->currentContextTag;
244 return (GLubyte *)(req) + sz_xGLXVendorPrivateReq;
247 const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 };
249 #define zero (__glXDefaultPixelStore+0)
250 #define one (__glXDefaultPixelStore+8)
251 #define default_pixel_store_1D (__glXDefaultPixelStore+4)
252 #define default_pixel_store_1D_size 20
253 #define default_pixel_store_2D (__glXDefaultPixelStore+4)
254 #define default_pixel_store_2D_size 20
255 #define default_pixel_store_3D (__glXDefaultPixelStore+0)
256 #define default_pixel_store_3D_size 36
257 #define default_pixel_store_4D (__glXDefaultPixelStore+0)
258 #define default_pixel_store_4D_size 36
261 for size
in self
.generic_sizes
:
262 self
.print_generic_function(size
)
265 def printFunction(self
, f
):
266 if f
.client_handcode
: return
268 if f
.glx_rop
!= 0 or f
.vectorequiv
!= None:
270 self
.printPixelFunction(f
)
272 self
.printRenderFunction(f
)
273 elif f
.glx_sop
!= 0 or f
.glx_vendorpriv
!= 0:
274 self
.printSingleFunction(f
)
276 print "/* Missing GLX protocol for %s. */" % (f
.name
)
278 def print_generic_function(self
, n
):
280 print """static FASTCALL NOINLINE void
281 generic_%u_byte( GLint rop, const void * ptr )
283 __GLXcontext * const gc = __glXGetCurrentContext();
284 const GLuint cmdlen = %u;
286 emit_header(gc->pc, rop, cmdlen);
287 (void) memcpy((void *)(gc->pc + 4), ptr, %u);
289 if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }
291 """ % (n
, size
+ 4, size
)
294 def common_emit_one_arg(self
, p
, offset
, pc
, indent
, adjust
):
299 src_ptr
= "&" + p
.name
301 print '%s (void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
302 % (indent
, pc
, offset
+ adjust
, src_ptr
, p
.size_string() )
304 def common_emit_args(self
, f
, pc
, indent
, adjust
, skip_vla
):
312 for p
in f
.parameterIterator(1, r
):
313 if p
.name
!= f
.img_reset
:
314 self
.common_emit_one_arg(p
, offset
, pc
, indent
, adjust
)
320 def pixel_emit_args(self
, f
, pc
, indent
, adjust
, dim
, large
):
321 """Emit the arguments for a pixel function. This differs from
322 common_emit_args in that pixel functions may require padding
323 be inserted (i.e., for the missing width field for
324 TexImage1D), and they may also require a 'NULL image' flag
325 be inserted before the image data."""
328 for p
in f
.parameterIterator(1, 1):
329 self
.common_emit_one_arg(p
, offset
, pc
, indent
, adjust
)
333 print '%s (void) memcpy((void *)(%s + %u), zero, 4);' % (indent
, pc
, offset
+ adjust
)
336 if f
.image
.img_null_flag
:
338 print '%s (void) memcpy((void *)(%s + %u), zero, 4);' % (indent
, pc
, offset
+ adjust
)
340 print '%s (void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (indent
, pc
, offset
+ adjust
, f
.image
.name
)
347 def large_emit_begin(self
, indent
, f
, op_name
= None):
349 op_name
= f
.opcode_real_name()
351 print '%s const GLint op = %s;' % (indent
, op_name
)
352 print '%s const GLuint cmdlenLarge = cmdlen + 4;' % (indent
)
353 print '%s GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);' % (indent
)
354 print '%s (void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);' % (indent
)
355 print '%s (void) memcpy((void *)(pc + 4), (void *)(&op), 4);' % (indent
)
359 def common_func_print_just_header(self
, f
):
360 print '#define %s %d' % (f
.opcode_name(), f
.opcode_value())
362 print '%s' % (f
.fn_return_type
)
363 print '__indirect_gl%s(%s)' % (f
.name
, f
.get_parameter_string())
367 def common_func_print_just_start(self
, f
):
368 print ' __GLXcontext * const gc = __glXGetCurrentContext();'
370 # The only reason that single and vendor private commands need
371 # a variable called 'dpy' is becuase they use the SyncHandle
372 # macro. For whatever brain-dead reason, that macro is hard-
373 # coded to use a variable called 'dpy' instead of taking a
377 if f
.image
and f
.image
.is_output
:
378 print ' const __GLXattribute * const state = gc->client_state_private;'
380 print ' Display * const dpy = gc->currentDpy;'
381 skip_condition
= "dpy != NULL"
383 skip_condition
= "gc->currentDpy != NULL"
385 skip_condition
= None
388 if f
.fn_return_type
!= 'void':
389 print ' %s retval = (%s) 0;' % (f
.fn_return_type
, f
.fn_return_type
)
391 if not f
.output_parameter():
392 compsize
= self
.size_call( f
)
394 print ' const GLuint compsize = %s;' % (compsize
)
396 print ' const GLuint cmdlen = %s;' % (f
.command_length())
400 skip_condition
= "(%s >= 0) && (%s)" % (f
.counter
, skip_condition
)
402 skip_condition
= "%s >= 0" % (f
.counter
)
406 print ' if (__builtin_expect(%s, 1)) {' % (skip_condition
)
412 def common_func_print_header(self
, f
):
413 self
.common_func_print_just_header(f
)
414 return self
.common_func_print_just_start(f
)
418 def printSingleFunction(self
, f
):
419 self
.common_func_print_header(f
)
422 print ' printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
423 if f
.glx_vendorpriv
== 0:
426 print '#ifdef USE_XCB'
428 print ' printf("\\tUsing XCB.\\n");'
429 print ' XCBConnection *c = XCBConnectionOfDisplay(dpy);'
430 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
431 xcb_name
= 'XCBGlx%s' % f
.name
433 for p
in f
.fn_parameters
:
435 iparams
.append(p
.name
)
437 if f
.image
and f
.image
.is_output
:
438 if f
.image
.img_format
!= "GL_COLOR_INDEX" or f
.image
.img_type
!= "GL_BITMAP":
439 iparams
.append("state->storePack.swapEndian")
443 # Hardcode this in. lsb_first param (apparently always GL_FALSE)
444 # also present in GetPolygonStipple, but taken care of above.
445 if xcb_name
== "XCBGlxReadPixels": iparams
.append("0")
447 xcb_request
= '%s(%s)' % (xcb_name
, ", ".join(["c", "gc->currentContextTag"] + iparams
))
450 print ' %sRep *reply = %sReply(c, %s, NULL);' % (xcb_name
, xcb_name
, xcb_request
)
451 if f
.output
and f
.reply_always_array
:
452 print ' %s = (%s *)%sData(reply);' % (f
.output
.name
, f
.output
.p_type
.name
, xcb_name
)
453 elif f
.output
and not f
.reply_always_array
:
454 if not f
.image
and not f
.name
== "GenQueriesARB":
455 print ' if (%sDataLength(reply) == 0)' % (xcb_name
)
456 print ' %s = (%s *) &reply->datum;' % (f
.output
.name
, f
.output
.p_type
.name
)
458 print ' %s = (%s *)%sData(reply);' % (f
.output
.name
, f
.output
.p_type
.name
, xcb_name
)
460 print ' %s = (%s *)%sData(reply);' % (f
.output
.name
, f
.output
.p_type
.name
, xcb_name
)
463 if f
.fn_return_type
!= 'void':
464 print ' retval = reply->ret_val;'
465 print ' free(reply);'
467 print ' ' + xcb_request
+ ';'
469 # End of XCB specific.
471 if f
.fn_parameters
!= []:
472 pc_decl
= "GLubyte const * pc ="
476 if f
.glx_vendorpriv
!= 0:
477 print ' %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl
, f
.opcode_real_name(), f
.opcode_name())
479 print ' %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl
, f
.opcode_name())
481 self
.common_emit_args(f
, "pc", " ", 0, 0)
482 if f
.image
and f
.image
.is_output
:
483 o
= f
.command_fixed_length() - 4
484 print ' *(int32_t *)(pc + %u) = 0;' % (o
)
485 if f
.image
.img_format
!= "GL_COLOR_INDEX" or f
.image
.img_type
!= "GL_BITMAP":
486 print ' * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o
)
489 print ' * (int8_t *)(pc + %u) = %s;' % (o
+ 1, f
.img_reset
)
493 if f
.image
and f
.image
.is_output
:
494 [dim
, w
, h
, d
, junk
] = f
.dimensions()
495 if f
.dimensions_in_reply
:
496 print " __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim
, f
.image
.img_format
, f
.image
.img_type
, f
.image
.name
)
498 print " __glXReadPixelReply(dpy, gc, %u, %s, %s, %s, %s, %s, %s, GL_FALSE);" % (dim
, w
, h
, d
, f
.image
.img_format
, f
.image
.img_type
, f
.image
.name
)
501 if f
.output
.p_type
.size
== 0:
504 output_size
= f
.output
.p_type
.size
506 output_str
= f
.output
.name
511 if f
.fn_return_type
!= 'void':
512 return_str
= " retval = (%s)" % (f
.fn_return_type
)
514 return_str
= " (void)"
516 if f
.reply_always_array
:
521 print " %s __glXReadReply(dpy, %s, %s, %s);" % (return_str
, output_size
, output_str
, aa
)
524 # Only emit the extra glFinish call for functions
525 # that don't already require a reply from the server.
526 print ' __indirect_glFinish();'
528 print ' UnlockDisplay(dpy); SyncHandle();'
530 if f
.glx_vendorpriv
== 0:
531 print '#endif /* USE_XCB */'
534 print ' printf( "Exit %%s.\\n", "gl%s" );' % (f
.name
)
536 print ' %s' % f
.return_string()
542 def printPixelFunction(self
, f
):
543 """This function could use some major refactoring. :("""
545 # There is a code-space optimization that we can do here.
546 # Functions that are marked img_pad_dimensions have a version
547 # with an odd number of dimensions and an even number of
548 # dimensions. TexSubImage1D and TexSubImage2D are examples.
549 # We can emit a single function that does both, and have the
550 # real functions call the utility function with the correct
553 # The only quirk to this is that utility funcitons will be
554 # generated for 3D and 4D functions, but 4D (e.g.,
555 # GL_SGIS_texture4D) isn't typically supported. This is
556 # probably not an issue. However, it would be possible to
557 # look at the total set of functions and determine if there
558 # is another function that would actually use the utility
559 # function. If not, then fallback to the normal way of
562 if f
.image
.img_pad_dimensions
:
563 # Determine the hash key and the name for the utility
564 # function that is used to implement the real
567 [h
, n
] = hash_pixel_function(f
)
570 # If the utility function is not yet known, generate
573 if not self
.pixel_stubs
.has_key(h
):
574 self
.pixel_stubs
[h
] = n
575 pixel_func
= glXPixelFunctionUtility(f
, n
)
578 print '%s( unsigned opcode, unsigned dim, %s )' % (n
, pixel_func
.get_parameter_string())
581 if self
.common_func_print_just_start(pixel_func
):
589 if pixel_func
.can_be_large
:
590 print '%s if (cmdlen <= gc->maxSmallRenderCommandSize) {' % (indent
)
591 print '%s if ( (gc->pc + cmdlen) > gc->bufEnd ) {' % (indent
)
592 print '%s (void) __glXFlushRenderBuffer(gc, gc->pc);' % (indent
)
593 print '%s }' % (indent
)
596 [dim
, width
, height
, depth
, extent
] = pixel_func
.dimensions()
597 adjust
= pixel_func
.offset_of_first_parameter() + 4
599 print '%s emit_header(gc->pc, opcode, cmdlen);' % (indent
)
601 offset
= self
.pixel_emit_args(pixel_func
, "gc->pc", indent
, adjust
, dim
, 0)
603 s
= pixel_func
.command_fixed_length()
605 pixHeaderPtr
= "gc->pc + 4"
606 pcPtr
= "gc->pc + %u" % (s
+ 4)
608 if pixel_func
.image
.img_send_null
:
609 condition
= '(compsize > 0) && (%s != NULL)' % (pixel_func
.image
.name
)
611 condition
= 'compsize > 0'
613 print '%s if (%s) {' % (indent
, condition
)
614 print '%s (*gc->fillImage)(gc, dim, %s, %s, %s, %s, %s, %s, %s, %s);' % (indent
, width
, height
, depth
, pixel_func
.image
.img_format
, pixel_func
.image
.img_type
, pixel_func
.image
.name
, pcPtr
, pixHeaderPtr
)
615 print '%s }' % (indent
)
616 print '%s else {' % (indent
)
617 print '%s (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (indent
, pixHeaderPtr
, dim
, dim
)
618 print '%s }' % (indent
)
620 print '%s gc->pc += cmdlen;' % (indent
)
621 print '%s if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent
)
626 print '%s}' % (indent
)
627 print '%selse {' % (indent
)
629 self
.large_emit_begin(indent
, pixel_func
, "opcode")
630 offset
= self
.pixel_emit_args(pixel_func
, "pc", indent
, adjust
, dim
, 1)
632 pixHeaderPtr
= "pc + 8"
633 pcPtr
= "pc + %u" % (s
+ 8)
635 print '%s __glXSendLargeImage(gc, compsize, dim, %s, %s, %s, %s, %s, %s, %s, %s);' % (indent
, width
, height
, depth
, f
.image
.img_format
, f
.image
.img_type
, f
.image
.name
, pcPtr
, pixHeaderPtr
)
637 print '%s}' % (indent
)
639 if trailer
: print trailer
645 # Generate the real function as a call to the
648 self
.common_func_print_just_header(f
)
650 [dim
, junk
, junk
, junk
, junk
] = f
.dimensions()
653 for p
in gl_XML
.glFunction
.parameterIterator(f
):
654 p_string
+= ", " + p
.name
659 print ' %s(%s, %u%s );' % (n
, f
.opcode_name(), dim
, p_string
)
665 if self
.common_func_print_header(f
):
674 print '%s if (cmdlen <= gc->maxSmallRenderCommandSize) {' % (indent
)
675 print '%s if ( (gc->pc + cmdlen) > gc->bufEnd ) {' % (indent
)
676 print '%s (void) __glXFlushRenderBuffer(gc, gc->pc);' % (indent
)
677 print '%s }' % (indent
)
680 [dim
, width
, height
, depth
, extent
] = f
.dimensions()
681 adjust
= f
.offset_of_first_parameter() + 4
683 print '%s emit_header(gc->pc, %s, cmdlen);' % (indent
, f
.opcode_real_name())
685 offset
= self
.pixel_emit_args(f
, "gc->pc", indent
, adjust
, dim
, 0)
687 s
= f
.command_fixed_length()
689 pixHeaderPtr
= "gc->pc + 4"
690 pcPtr
= "gc->pc + %u" % (s
+ 4)
692 if f
.image
.img_send_null
:
693 condition
= '(compsize > 0) && (%s != NULL)' % (f
.image
.name
)
695 condition
= 'compsize > 0'
697 print '%s if (%s) {' % (indent
, condition
)
698 print '%s (*gc->fillImage)(gc, %u, %s, %s, %s, %s, %s, %s, %s, %s);' % (indent
, dim
, width
, height
, depth
, f
.image
.img_format
, f
.image
.img_type
, f
.image
.name
, pcPtr
, pixHeaderPtr
)
699 print '%s }' % (indent
)
700 print '%s else {' % (indent
)
701 print '%s (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (indent
, pixHeaderPtr
, dim
, dim
)
702 print '%s }' % (indent
)
704 print '%s gc->pc += cmdlen;' % (indent
)
705 print '%s if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent
)
710 print '%s}' % (indent
)
711 print '%selse {' % (indent
)
713 self
.large_emit_begin(indent
, f
)
714 offset
= self
.pixel_emit_args(f
, "pc", indent
, adjust
, dim
, 1)
716 pixHeaderPtr
= "pc + 8"
717 pcPtr
= "pc + %u" % (s
+ 8)
719 print '%s __glXSendLargeImage(gc, compsize, %u, %s, %s, %s, %s, %s, %s, %s, %s);' % (indent
, dim
, width
, height
, depth
, f
.image
.img_format
, f
.image
.img_type
, f
.image
.name
, pcPtr
, pixHeaderPtr
)
721 print '%s}' % (indent
)
723 if trailer
: print trailer
729 def printRenderFunction(self
, f
):
730 # There is a class of GL functions that take a single pointer
731 # as a parameter. This pointer points to a fixed-size chunk
732 # of data, and the protocol for this functions is very
733 # regular. Since they are so regular and there are so many
734 # of them, special case them with generic functions. On
735 # x86, this saves about 26KB in the libGL.so binary.
737 if f
.variable_length_parameter() == None and len(f
.fn_parameters
) == 1:
738 p
= f
.fn_parameters
[0]
740 cmdlen
= f
.command_fixed_length()
741 if cmdlen
in self
.generic_sizes
:
742 self
.common_func_print_just_header(f
)
743 print ' generic_%u_byte( %s, %s );' % (cmdlen
, f
.opcode_real_name(), p
.name
)
748 if self
.common_func_print_header(f
):
756 print '%s printf( "Enter %%s...\\n", "gl%s" );' % (indent
, f
.name
)
759 print '%s if (cmdlen <= gc->maxSmallRenderCommandSize) {' % (indent
)
760 print '%s if ( (gc->pc + cmdlen) > gc->bufEnd ) {' % (indent
)
761 print '%s (void) __glXFlushRenderBuffer(gc, gc->pc);' % (indent
)
762 print '%s }' % (indent
)
765 print '%s emit_header(gc->pc, %s, cmdlen);' % (indent
, f
.opcode_real_name())
767 self
.common_emit_args(f
, "gc->pc", indent
, 4, 0)
768 print '%s gc->pc += cmdlen;' % (indent
)
769 print '%s if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent
)
772 print '%s}' % (indent
)
773 print '%selse {' % (indent
)
775 self
.large_emit_begin(indent
, f
)
776 offset
= self
.common_emit_args(f
, "pc", indent
, 8, 1)
778 p
= f
.variable_length_parameter()
779 print '%s __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (indent
, offset
+ 8, p
.name
, p
.size_string())
780 print '%s}' % (indent
)
783 print '%s __indirect_glFinish();' % (indent
)
784 print '%s printf( "Exit %%s.\\n", "gl%s" );' % (indent
, f
.name
)
786 if trailer
: print trailer
792 class PrintGlxProtoInit_c(glX_XML
.GlxProto
):
794 glX_XML
.GlxProto
.__init
__(self
)
795 self
.last_category
= ""
796 self
.license
= license
.bsd_license_template
% ( \
797 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
798 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
801 def printRealHeader(self
):
803 * \\file indirect_init.c
804 * Initialize indirect rendering dispatch table.
806 * \\author Kevin E. Martin <kevin@precisioninsight.com>
807 * \\author Brian Paul <brian@precisioninsight.com>
808 * \\author Ian Romanick <idr@us.ibm.com>
811 #include "indirect_init.h"
812 #include "indirect.h"
817 * No-op function used to initialize functions that have no GLX protocol
820 static int NoOp(void)
826 * Create and initialize a new GL dispatch table. The table is initialized
827 * with GLX indirect rendering protocol functions.
829 __GLapi * __glXNewIndirectAPI( void )
834 entries = _glapi_get_dispatch_table_size();
835 glAPI = (__GLapi *) Xmalloc(entries * sizeof(void *));
837 /* first, set all entries to point to no-op functions */
840 void **dispatch = (void **) glAPI;
841 for (i = 0; i < entries; i++) {
842 dispatch[i] = (void *) NoOp;
846 /* now, initialize the entries we understand */"""
848 def printRealFooter(self
):
854 def printFunction(self
, f
):
855 if f
.category
!= self
.last_category
:
856 self
.last_category
= f
.category
858 print ' /* %s */' % (self
.last_category
)
861 print ' glAPI->%s = __indirect_gl%s;' % (f
.name
, f
.name
)
864 class PrintGlxProtoInit_h(glX_XML
.GlxProto
):
866 glX_XML
.GlxProto
.__init
__(self
)
867 self
.last_category
= ""
868 self
.license
= license
.bsd_license_template
% ( \
869 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
870 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
871 self
.header_tag
= "_INDIRECT_H_"
873 def printRealHeader(self
):
876 * Prototypes for indirect rendering functions.
878 * \\author Kevin E. Martin <kevin@precisioninsight.com>
879 * \\author Ian Romanick <idr@us.ibm.com>
882 self
.printVisibility( "HIDDEN", "hidden" )
887 #include "glxclient.h"
889 extern HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
890 void * dest, GLboolean reply_is_always_array );
892 extern HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
893 __GLXcontext * gc, unsigned max_dim, GLint width, GLint height,
894 GLint depth, GLenum format, GLenum type, void * dest,
895 GLboolean dimensions_in_reply );
897 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
898 __GLXcontext * gc, GLint sop, GLint cmdlen );
900 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
901 __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen );
905 def printFunction(self
, f
):
906 print 'extern HIDDEN %s __indirect_gl%s(%s);' % (f
.fn_return_type
, f
.name
, f
.get_parameter_string())
910 print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys
.argv
[0]
911 print " -m output_mode Output mode can be one of 'proto', 'init_c' or 'init_h'."
912 print " -d Enable extra debug information in the generated code."
916 if __name__
== '__main__':
917 file_name
= "gl_API.xml"
920 (args
, trail
) = getopt
.getopt(sys
.argv
[1:], "f:m:d")
926 for (arg
,val
) in args
:
935 dh
= PrintGlxProtoStubs()
936 elif mode
== "init_c":
937 dh
= PrintGlxProtoInit_c()
938 elif mode
== "init_h":
939 dh
= PrintGlxProtoInit_h()
945 gl_XML
.parse_GL_API( dh
, file_name
)