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>
28 import gl_XML
, glX_XML
, glX_proto_common
, license
29 import sys
, getopt
, copy
, string
31 def hash_pixel_function(func
):
32 """Generate a 'unique' key for a pixel function. The key is based on
33 the parameters written in the command packet. This includes any
34 padding that might be added for the original function and the 'NULL
41 for param
in func
.parameterIterateGlxSend():
43 [dim
, junk
, junk
, junk
, junk
] = param
.get_dimensions()
46 hash_pre
= "%uD%uD_" % (d
- 1, d
)
48 if param
.img_null_flag
:
51 h
+= "%u" % (param
.size())
53 if func
.pad_after(param
):
57 n
= func
.name
.replace("%uD" % (dim
), "")
58 n
= "__glx_%s_%uD%uD" % (n
, d
- 1, d
)
60 h
= hash_pre
+ h
+ hash_suf
64 class glx_pixel_function_stub(glX_XML
.glx_function
):
65 """Dummy class used to generate pixel "utility" functions that are
66 shared by multiple dimension image functions. For example, these
67 objects are used to generate shared functions used to send GLX
68 protocol for TexImage1D and TexImage2D, TexSubImage1D and
69 TexSubImage2D, etc."""
71 def __init__(self
, func
, name
):
72 # The parameters to the utility function are the same as the
73 # parameters to the real function except for the added "pad"
79 self
.parameters_by_name
= {}
80 for _p
in func
.parameterIterator():
82 self
.parameters
.append(p
)
83 self
.parameters_by_name
[ p
.name
] = p
90 if p
.img_yoff
== None:
91 p
.img_yoff
= "yoffset"
97 if p
.img_woff
== None:
98 p
.img_woff
= "woffset"
101 pad_name
= func
.pad_after(p
)
105 self
.parameters
.append(pad
)
106 self
.parameters_by_name
[ pad
.name
] = pad
109 self
.return_type
= func
.return_type
113 self
.glx_vendorpriv
= 0
115 self
.glx_doubles_in_order
= func
.glx_doubles_in_order
117 self
.vectorequiv
= None
119 self
.can_be_large
= func
.can_be_large
120 self
.reply_always_array
= func
.reply_always_array
121 self
.dimensions_in_reply
= func
.dimensions_in_reply
122 self
.img_reset
= None
124 self
.server_handcode
= 0
125 self
.client_handcode
= 0
128 self
.count_parameter_list
= func
.count_parameter_list
129 self
.counter_list
= func
.counter_list
130 self
.offsets_calculated
= 0
134 class PrintGlxProtoStubs(glX_proto_common
.glx_print_proto
):
136 glX_proto_common
.glx_print_proto
.__init
__(self
)
137 self
.name
= "glX_proto_send.py (from Mesa)"
138 self
.license
= license
.bsd_license_template
% ( "(C) Copyright IBM Corporation 2004, 2005", "IBM")
141 self
.last_category
= ""
142 self
.generic_sizes
= [3, 4, 6, 8, 12, 16, 24, 32]
143 self
.pixel_stubs
= {}
147 def printRealHeader(self
):
149 print '#include <GL/gl.h>'
150 print '#include "indirect.h"'
151 print '#include "glxclient.h"'
152 print '#include "indirect_size.h"'
153 print '#include <GL/glxproto.h>'
154 print '#ifdef USE_XCB'
155 print '#include <X11/xcl.h>'
156 print '#include <X11/XCB/xcb.h>'
157 print '#include <X11/XCB/glx.h>'
158 print '#endif /* USE_XCB */'
161 print '#define __GLX_PAD(n) (((n) + 3) & ~3)'
166 print '#if !defined __GNUC__ || __GNUC__ < 3'
167 print '# define __builtin_expect(x, y) x'
170 print '/* If the size and opcode values are known at compile-time, this will, on'
171 print ' * x86 at least, emit them with a single instruction.'
173 print '#define emit_header(dest, op, size) \\'
174 print ' do { union { short s[2]; int i; } temp; \\'
175 print ' temp.s[0] = (size); temp.s[1] = (op); \\'
176 print ' *((int *)(dest)) = temp.i; } while(0)'
178 print """NOINLINE CARD32
179 __glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array )
181 xGLXSingleReply reply;
183 (void) _XReply(dpy, (xReply *) & reply, 0, False);
185 if ((reply.length > 0) || reply_is_always_array) {
186 const GLint bytes = (reply_is_always_array)
187 ? (4 * reply.length) : (reply.size * size);
188 const GLint extra = 4 - (bytes & 3);
190 _XRead(dpy, dest, bytes);
192 _XEatData(dpy, extra);
196 (void) memcpy( dest, &(reply.pad3), size);
204 __glXReadPixelReply( Display *dpy, __GLXcontext * gc, unsigned max_dim,
205 GLint width, GLint height, GLint depth, GLenum format, GLenum type,
206 void * dest, GLboolean dimensions_in_reply )
208 xGLXSingleReply reply;
211 (void) _XReply(dpy, (xReply *) & reply, 0, False);
213 if ( dimensions_in_reply ) {
218 if ((height == 0) || (max_dim < 2)) { height = 1; }
219 if ((depth == 0) || (max_dim < 3)) { depth = 1; }
222 size = reply.length * 4;
224 void * buf = Xmalloc( size );
227 _XEatData(dpy, size);
228 __glXSetError(gc, GL_OUT_OF_MEMORY);
231 const GLint extra = 4 - (size & 3);
233 _XRead(dpy, buf, size);
235 _XEatData(dpy, extra);
238 __glEmptyImage(gc, 3, width, height, depth, format, type,
245 #define X_GLXSingle 0
247 NOINLINE FASTCALL GLubyte *
248 __glXSetupSingleRequest( __GLXcontext * gc, GLint sop, GLint cmdlen )
251 Display * const dpy = gc->currentDpy;
253 (void) __glXFlushRenderBuffer(gc, gc->pc);
255 GetReqExtra(GLXSingle, cmdlen, req);
256 req->reqType = gc->majorOpcode;
257 req->contextTag = gc->currentContextTag;
259 return (GLubyte *)(req) + sz_xGLXSingleReq;
262 NOINLINE FASTCALL GLubyte *
263 __glXSetupVendorRequest( __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen )
265 xGLXVendorPrivateReq * req;
266 Display * const dpy = gc->currentDpy;
268 (void) __glXFlushRenderBuffer(gc, gc->pc);
270 GetReqExtra(GLXVendorPrivate, cmdlen, req);
271 req->reqType = gc->majorOpcode;
273 req->vendorCode = vop;
274 req->contextTag = gc->currentContextTag;
275 return (GLubyte *)(req) + sz_xGLXVendorPrivateReq;
278 const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 };
280 #define zero (__glXDefaultPixelStore+0)
281 #define one (__glXDefaultPixelStore+8)
282 #define default_pixel_store_1D (__glXDefaultPixelStore+4)
283 #define default_pixel_store_1D_size 20
284 #define default_pixel_store_2D (__glXDefaultPixelStore+4)
285 #define default_pixel_store_2D_size 20
286 #define default_pixel_store_3D (__glXDefaultPixelStore+0)
287 #define default_pixel_store_3D_size 36
288 #define default_pixel_store_4D (__glXDefaultPixelStore+0)
289 #define default_pixel_store_4D_size 36
292 for size
in self
.generic_sizes
:
293 self
.print_generic_function(size
)
297 def printBody(self
, api
):
299 self
.pixel_stubs
= {}
302 for func
in api
.functionIterateGlx():
303 if func
.client_handcode
: continue
305 # If the function is a pixel function with a certain
306 # GLX protocol signature, create a fake stub function
307 # for it. For example, create a single stub function
308 # that is used to implement both glTexImage1D and
311 if func
.glx_rop
!= 0:
313 for image
in func
.get_images():
314 if image
.img_pad_dimensions
:
320 [h
, n
] = hash_pixel_function(func
)
323 self
.pixel_stubs
[ func
.name
] = n
324 if h
not in generated_stubs
:
325 generated_stubs
.append(h
)
327 fake_func
= glx_pixel_function_stub( func
, n
)
328 self
.printFunction( fake_func
)
331 self
.printFunction( func
)
336 def printFunction(self
, func
):
337 if func
.glx_rop
== ~
0:
338 print 'static %s' % (func
.return_type
)
339 print '%s( unsigned opcode, unsigned dim, %s )' % (func
.name
, func
.get_parameter_string())
341 print '#define %s %d' % (func
.opcode_name(), func
.opcode_value())
343 print '%s' % (func
.return_type
)
344 print '__indirect_gl%s(%s)' % (func
.name
, func
.get_parameter_string())
350 if func
.glx_rop
!= 0 or func
.vectorequiv
!= None:
352 self
.printPixelFunction(func
)
354 self
.printRenderFunction(func
)
355 elif func
.glx_sop
!= 0 or func
.glx_vendorpriv
!= 0:
356 self
.printSingleFunction(func
)
359 print "/* Missing GLX protocol for %s. */" % (func
.name
)
367 def print_generic_function(self
, n
):
369 print """static FASTCALL NOINLINE void
370 generic_%u_byte( GLint rop, const void * ptr )
372 __GLXcontext * const gc = __glXGetCurrentContext();
373 const GLuint cmdlen = %u;
375 emit_header(gc->pc, rop, cmdlen);
376 (void) memcpy((void *)(gc->pc + 4), ptr, %u);
378 if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }
380 """ % (n
, size
+ 4, size
)
384 def common_emit_one_arg(self
, p
, pc
, indent
, adjust
, extra_offset
):
388 src_ptr
= "&" + p
.name
391 print '%s (void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
392 % (indent
, pc
, p
.offset
+ adjust
, src_ptr
, p
.size_string() )
394 print '%s (void) memcpy((void *)(%s + %u + %s), (void *)(%s), %s);' \
395 % (indent
, pc
, p
.offset
+ adjust
, extra_offset
, src_ptr
, p
.size_string() )
397 def common_emit_args(self
, f
, pc
, indent
, adjust
, skip_vla
):
400 for p
in f
.parameterIterateGlxSend( not skip_vla
):
401 if p
.name
!= f
.img_reset
:
402 self
.common_emit_one_arg(p
, pc
, indent
, adjust
, extra_offset
)
404 if p
.is_variable_length():
405 temp
= p
.size_string()
407 extra_offset
+= " + %s" % (temp
)
414 def pixel_emit_args(self
, f
, pc
, indent
, large
):
415 """Emit the arguments for a pixel function. This differs from
416 common_emit_args in that pixel functions may require padding
417 be inserted (i.e., for the missing width field for
418 TexImage1D), and they may also require a 'NULL image' flag
419 be inserted before the image data."""
426 for param
in f
.parameterIterateGlxSend():
427 if not param
.is_image():
428 self
.common_emit_one_arg(param
, pc
, indent
, adjust
, None)
430 if f
.pad_after(param
):
431 print '%s (void) memcpy((void *)(%s + %u), zero, 4);' % (indent
, pc
, (param
.offset
+ param
.size()) + adjust
)
434 [dim
, width
, height
, depth
, extent
] = param
.get_dimensions()
440 if param
.img_null_flag
:
442 print '%s (void) memcpy((void *)(%s + %u), zero, 4);' % (indent
, pc
, (param
.offset
- 4) + adjust
)
444 print '%s (void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (indent
, pc
, (param
.offset
- 4) + adjust
, param
.name
)
447 pixHeaderPtr
= "%s + %u" % (pc
, adjust
)
448 pcPtr
= "%s + %u" % (pc
, param
.offset
+ adjust
)
451 if param
.img_send_null
:
452 condition
= '(compsize > 0) && (%s != NULL)' % (param
.name
)
454 condition
= 'compsize > 0'
456 print '%s if (%s) {' % (indent
, condition
)
457 print '%s (*gc->fillImage)(gc, %s, %s, %s, %s, %s, %s, %s, %s, %s);' % (indent
, dim_str
, width
, height
, depth
, param
.img_format
, param
.img_type
, param
.name
, pcPtr
, pixHeaderPtr
)
458 print '%s }' % (indent
)
459 print '%s else {' % (indent
)
460 print '%s (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (indent
, pixHeaderPtr
, dim
, dim
)
461 print '%s }' % (indent
)
463 print '%s __glXSendLargeImage(gc, compsize, %s, %s, %s, %s, %s, %s, %s, %s, %s);' % (indent
, dim_str
, width
, height
, depth
, param
.img_format
, param
.img_type
, param
.name
, pcPtr
, pixHeaderPtr
)
468 def large_emit_begin(self
, indent
, f
, op_name
= None):
470 op_name
= f
.opcode_real_name()
472 print '%s const GLint op = %s;' % (indent
, op_name
)
473 print '%s const GLuint cmdlenLarge = cmdlen + 4;' % (indent
)
474 print '%s GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);' % (indent
)
475 print '%s (void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);' % (indent
)
476 print '%s (void) memcpy((void *)(pc + 4), (void *)(&op), 4);' % (indent
)
480 def common_func_print_just_start(self
, f
):
481 print ' __GLXcontext * const gc = __glXGetCurrentContext();'
483 # The only reason that single and vendor private commands need
484 # a variable called 'dpy' is becuase they use the SyncHandle
485 # macro. For whatever brain-dead reason, that macro is hard-
486 # coded to use a variable called 'dpy' instead of taking a
489 # FIXME Simplify the logic related to skip_condition and
490 # FIXME condition_list in this function. Basically, remove
491 # FIXME skip_condition, and just append the "dpy != NULL" type
492 # FIXME condition to condition_list from the start. The only
493 # FIXME reason it's done in this confusing way now is to
494 # FIXME minimize the diffs in the generated code.
497 for p
in f
.parameterIterateOutputs():
499 print ' const __GLXattribute * const state = gc->client_state_private;'
502 print ' Display * const dpy = gc->currentDpy;'
503 skip_condition
= "dpy != NULL"
505 skip_condition
= "gc->currentDpy != NULL"
507 skip_condition
= None
510 if f
.return_type
!= 'void':
511 print ' %s retval = (%s) 0;' % (f
.return_type
, f
.return_type
)
514 self
.emit_packet_size_calculation(f
, 0)
517 for p
in f
.parameterIterateCounters():
518 condition_list
.append( "%s >= 0" % (p
.name
) )
521 condition_list
.append( skip_condition
)
523 if len( condition_list
) > 0:
524 if len( condition_list
) > 1:
525 skip_condition
= "(%s)" % (string
.join( condition_list
, ") && (" ))
527 skip_condition
= "%s" % (condition_list
.pop(0))
529 print ' if (__builtin_expect(%s, 1)) {' % (skip_condition
)
535 def printSingleFunction(self
, f
):
536 self
.common_func_print_just_start(f
)
539 print ' printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
541 if f
.glx_vendorpriv
== 0:
544 print '#ifdef USE_XCB'
546 print ' printf("\\tUsing XCB.\\n");'
547 print ' XCBConnection *c = XCBConnectionOfDisplay(dpy);'
548 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
549 xcb_name
= 'XCBGlx%s' % f
.name
554 for p
in f
.parameterIterator():
559 if p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP":
560 extra_iparams
.append("state->storePack.swapEndian")
562 extra_iparams
.append("0")
564 # Hardcode this in. lsb_first param (apparently always GL_FALSE)
565 # also present in GetPolygonStipple, but taken care of above.
566 if xcb_name
== "XCBGlxReadPixels":
567 extra_iparams
.append("0")
569 iparams
.append(p
.name
)
572 xcb_request
= '%s(%s)' % (xcb_name
, ", ".join(["c", "gc->currentContextTag"] + iparams
+ extra_iparams
))
575 print ' %sRep *reply = %sReply(c, %s, NULL);' % (xcb_name
, xcb_name
, xcb_request
)
576 if output
and f
.reply_always_array
:
577 print ' (void)memcpy(%s, %sData(reply), %sDataLength(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
579 elif output
and not f
.reply_always_array
:
580 if not output
.is_image():
581 print ' if (%sDataLength(reply) == 0)' % (xcb_name
)
582 print ' (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output
.name
)
584 print ' (void)memcpy(%s, %sData(reply), %sDataLength(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
587 if f
.return_type
!= 'void':
588 print ' retval = reply->ret_val;'
589 print ' free(reply);'
591 print ' ' + xcb_request
+ ';'
593 # End of XCB specific.
596 if f
.parameters
!= []:
597 pc_decl
= "GLubyte const * pc ="
601 if f
.glx_vendorpriv
!= 0:
602 print ' %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl
, f
.opcode_real_name(), f
.opcode_name())
604 print ' %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl
, f
.opcode_name())
606 self
.common_emit_args(f
, "pc", " ", 0, 0)
608 images
= f
.get_images()
612 o
= f
.command_fixed_length() - 4
613 print ' *(int32_t *)(pc + %u) = 0;' % (o
)
614 if img
.img_format
!= "GL_COLOR_INDEX" or img
.img_type
!= "GL_BITMAP":
615 print ' * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o
)
618 print ' * (int8_t *)(pc + %u) = %s;' % (o
+ 1, f
.img_reset
)
623 if f
.return_type
!= 'void':
624 return_name
= " retval"
625 return_str
= " retval = (%s)" % (f
.return_type
)
627 return_str
= " (void)"
631 for p
in f
.parameterIterateOutputs():
633 [dim
, w
, h
, d
, junk
] = p
.get_dimensions()
634 if f
.dimensions_in_reply
:
635 print " __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim
, p
.img_format
, p
.img_type
, p
.name
)
637 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
)
641 if f
.reply_always_array
:
646 # gl_parameter.size() returns the size
647 # of the entire data item. If the
648 # item is a fixed-size array, this is
649 # the size of the whole array. This
650 # is not what __glXReadReply wants. It
651 # wants the size of a single data
652 # element in the reply packet.
653 # Dividing by the array size (1 for
654 # non-arrays) gives us this.
656 s
= p
.size() / p
.get_element_count()
657 print " %s __glXReadReply(dpy, %s, %s, %s);" % (return_str
, s
, p
.name
, aa
)
661 # If a reply wasn't read to fill an output parameter,
662 # read a NULL reply to get the return value.
665 print " %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str
)
669 # Only emit the extra glFinish call for functions
670 # that don't already require a reply from the server.
671 print ' __indirect_glFinish();'
674 print ' printf( "Exit %%s.\\n", "gl%s" );' % (f
.name
)
677 print ' UnlockDisplay(dpy); SyncHandle();'
679 if f
.glx_vendorpriv
== 0:
680 print '#endif /* USE_XCB */'
683 print ' return%s;' % (return_name
)
687 def printPixelFunction(self
, f
):
688 if self
.pixel_stubs
.has_key( f
.name
):
689 # Normally gl_function::get_parameter_string could be
690 # used. However, this call needs to have the missing
691 # dimensions (e.g., a fake height value for
692 # glTexImage1D) added in.
695 for param
in f
.parameterIterateGlxSend():
696 p_string
+= ", " + param
.name
699 [dim
, junk
, junk
, junk
, junk
] = param
.get_dimensions()
701 if f
.pad_after(param
):
704 print ' %s(%s, %u%s );' % (self
.pixel_stubs
[f
.name
] , f
.opcode_name(), dim
, p_string
)
708 if self
.common_func_print_just_start(f
):
717 print '%s if (cmdlen <= gc->maxSmallRenderCommandSize) {' % (indent
)
718 print '%s if ( (gc->pc + cmdlen) > gc->bufEnd ) {' % (indent
)
719 print '%s (void) __glXFlushRenderBuffer(gc, gc->pc);' % (indent
)
720 print '%s }' % (indent
)
726 opcode
= f
.opcode_real_name()
728 print '%s emit_header(gc->pc, %s, cmdlen);' % (indent
, opcode
)
730 self
.pixel_emit_args( f
, "gc->pc", indent
, 0 )
731 print '%s gc->pc += cmdlen;' % (indent
)
732 print '%s if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent
)
735 print '%s}' % (indent
)
736 print '%selse {' % (indent
)
738 self
.large_emit_begin(indent
, f
, opcode
)
739 self
.pixel_emit_args( f
, "pc", indent
, 1 )
741 print '%s}' % (indent
)
743 if trailer
: print trailer
747 def printRenderFunction(self
, f
):
748 # There is a class of GL functions that take a single pointer
749 # as a parameter. This pointer points to a fixed-size chunk
750 # of data, and the protocol for this functions is very
751 # regular. Since they are so regular and there are so many
752 # of them, special case them with generic functions. On
753 # x86, this saves about 26KB in the libGL.so binary.
755 if f
.variable_length_parameter() == None and len(f
.parameters
) == 1:
758 cmdlen
= f
.command_fixed_length()
759 if cmdlen
in self
.generic_sizes
:
760 print ' generic_%u_byte( %s, %s );' % (cmdlen
, f
.opcode_real_name(), p
.name
)
763 if self
.common_func_print_just_start(f
):
771 print '%s printf( "Enter %%s...\\n", "gl%s" );' % (indent
, f
.name
)
774 print '%s if (cmdlen <= gc->maxSmallRenderCommandSize) {' % (indent
)
775 print '%s if ( (gc->pc + cmdlen) > gc->bufEnd ) {' % (indent
)
776 print '%s (void) __glXFlushRenderBuffer(gc, gc->pc);' % (indent
)
777 print '%s }' % (indent
)
780 print '%s emit_header(gc->pc, %s, cmdlen);' % (indent
, f
.opcode_real_name())
782 self
.common_emit_args(f
, "gc->pc", indent
, 4, 0)
783 print '%s gc->pc += cmdlen;' % (indent
)
784 print '%s if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent
)
787 print '%s}' % (indent
)
788 print '%selse {' % (indent
)
790 self
.large_emit_begin(indent
, f
)
791 self
.common_emit_args(f
, "pc", indent
, 8, 1)
793 p
= f
.variable_length_parameter()
794 print '%s __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (indent
, p
.offset
+ 8, p
.name
, p
.size_string())
795 print '%s}' % (indent
)
798 print '%s __indirect_glFinish();' % (indent
)
799 print '%s printf( "Exit %%s.\\n", "gl%s" );' % (indent
, f
.name
)
801 if trailer
: print trailer
805 class PrintGlxProtoInit_c(gl_XML
.gl_print_base
):
807 gl_XML
.gl_print_base
.__init
__(self
)
809 self
.name
= "glX_proto_send.py (from Mesa)"
810 self
.license
= license
.bsd_license_template
% ( \
811 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
812 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
816 def printRealHeader(self
):
818 * \\file indirect_init.c
819 * Initialize indirect rendering dispatch table.
821 * \\author Kevin E. Martin <kevin@precisioninsight.com>
822 * \\author Brian Paul <brian@precisioninsight.com>
823 * \\author Ian Romanick <idr@us.ibm.com>
826 #include "indirect_init.h"
827 #include "indirect.h"
832 * No-op function used to initialize functions that have no GLX protocol
835 static int NoOp(void)
841 * Create and initialize a new GL dispatch table. The table is initialized
842 * with GLX indirect rendering protocol functions.
844 __GLapi * __glXNewIndirectAPI( void )
849 entries = _glapi_get_dispatch_table_size();
850 glAPI = (__GLapi *) Xmalloc(entries * sizeof(void *));
852 /* first, set all entries to point to no-op functions */
855 void **dispatch = (void **) glAPI;
856 for (i = 0; i < entries; i++) {
857 dispatch[i] = (void *) NoOp;
861 /* now, initialize the entries we understand */"""
863 def printRealFooter(self
):
871 def printCategory(self
, category_group
, show_num
):
872 cat_keys
= category_group
.keys()
874 for cat_num
in cat_keys
:
876 for offset
in category_group
[ cat_num
]:
877 [cat_name
, func_name
] = category_group
[ cat_num
][ offset
]
882 print ' /* % 3u. %s */' % (cat_num
, cat_name
)
884 print ' /* %s */' % (cat_name
)
888 print ' glAPI->%s = __indirect_gl%s;' % (func_name
, func_name
)
891 def printBody(self
, api
):
894 other_categories
= {}
897 for func
in api
.functionIterateGlx():
898 [cat
, num
] = api
.get_category_for_name( func
.name
)
900 # There are three groups of "categories" that we
901 # care about here. We want to separate the core GL
902 # version categories from extensions. We also want to
903 # separate the ARB extensions from the non-ARB
906 # This is done by first trying to convert the category
907 # name to a floating point number. All core GL
908 # versions are of the form "N.M" where both N and M
909 # are integers. If the cast to float fails, an
910 # exception will be thrown. Once down that path,
911 # we can look at the start of the extension string.
912 # If it begins with "GL_ARB_", it's an ARB extension.
914 # Once the categories are separated, the are ordered
915 # by number. The un-numbered non-ARB extensions
916 # (e.g., GL_INGR_blend_func_separate) are assigned
917 # arbitrary numbers starting at 1000.
919 # FIXME In order to maintain repeatability, the
920 # FIXME unnumbered extensions should be put in their
921 # FIXME own dictionary and ordered by name (since they
922 # FIXME have no number).
926 if not core_categories
.has_key( num
):
927 core_categories
[ num
] = {}
929 core_categories
[ num
][ func
.offset
] = [cat
, func
.name
]
938 if cat
.startswith( "GL_ARB_" ):
939 if not arb_categories
.has_key( num
):
940 arb_categories
[ num
] = {}
942 arb_categories
[ num
][ func
.offset
] = [cat
, func
.name
]
944 if not other_categories
.has_key( num
):
945 other_categories
[ num
] = {}
947 other_categories
[ num
][ func
.offset
] = [cat
, func
.name
]
949 self
.printCategory( core_categories
, 0 )
950 self
.printCategory( arb_categories
, 1 )
951 self
.printCategory( other_categories
, 1 )
955 class PrintGlxProtoInit_h(gl_XML
.gl_print_base
):
957 gl_XML
.gl_print_base
.__init
__(self
)
959 self
.name
= "glX_proto_send.py (from Mesa)"
960 self
.license
= license
.bsd_license_template
% ( \
961 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
962 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
963 self
.header_tag
= "_INDIRECT_H_"
965 self
.last_category
= ""
969 def printRealHeader(self
):
972 * Prototypes for indirect rendering functions.
974 * \\author Kevin E. Martin <kevin@precisioninsight.com>
975 * \\author Ian Romanick <idr@us.ibm.com>
978 self
.printVisibility( "HIDDEN", "hidden" )
983 #include "glxclient.h"
985 extern HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
986 void * dest, GLboolean reply_is_always_array );
988 extern HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
989 __GLXcontext * gc, unsigned max_dim, GLint width, GLint height,
990 GLint depth, GLenum format, GLenum type, void * dest,
991 GLboolean dimensions_in_reply );
993 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
994 __GLXcontext * gc, GLint sop, GLint cmdlen );
996 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
997 __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen );
1001 def printBody(self
, api
):
1002 for func
in api
.functionIterateGlx():
1003 print 'extern HIDDEN %s __indirect_gl%s(%s);' % (func
.return_type
, func
.name
, func
.get_parameter_string())
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
)