Convert all Python scripts to use XML namespaces.
[mesa.git] / src / mesa / glapi / glX_proto_send.py
1 #!/usr/bin/python2
2
3 # (C) Copyright IBM Corporation 2004, 2005
4 # All Rights Reserved.
5 #
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:
12 #
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
15 # Software.
16 #
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
23 # IN THE SOFTWARE.
24 #
25 # Authors:
26 # Ian Romanick <idr@us.ibm.com>
27
28 from xml.sax import saxutils
29 from xml.sax import make_parser
30 from xml.sax.handler import feature_namespaces
31
32 import gl_XML
33 import glX_XML
34 import license
35 import sys, getopt, copy
36
37 def hash_pixel_function(func):
38 """Generate a 'unique' key for a pixel function. The key is based on
39 the parameters written in the command packet. This includes any
40 padding that might be added for the original function and the 'NULL
41 image' flag."""
42
43 [dim, junk, junk, junk, junk] = func.dimensions()
44
45 d = (dim + 1) & ~1
46 h = "%uD%uD_" % (d - 1, d)
47
48 for p in func.parameterIterator(1, 1):
49 h = "%s%u" % (h, p.size())
50
51 if func.pad_after(p):
52 h += "4"
53
54 if func.image.img_null_flag:
55 h += "_NF"
56
57 n = func.name.replace("%uD" % (dim), "")
58 n = "__glx_%s_%uD%uD" % (n, d - 1, d)
59 return [h, n]
60
61
62 class glXPixelFunctionUtility(glX_XML.glXFunction):
63 """Dummy class used to generate pixel "utility" functions that are
64 shared by multiple dimension image functions. For example, these
65 objects are used to generate shared functions used to send GLX
66 protocol for TexImage1D and TexImage2D, TexSubImage1D and
67 TexSubImage2D, etc."""
68
69 def __init__(self, func, name):
70 # The parameters to the utility function are the same as the
71 # parameters to the real function except for the added "pad"
72 # parameters.
73
74 self.name = name
75 self.image = copy.copy(func.image)
76 self.fn_parameters = []
77 for p in gl_XML.glFunction.parameterIterator(func):
78 self.fn_parameters.append(p)
79
80 pad_name = func.pad_after(p)
81 if pad_name:
82 pad = copy.copy(p)
83 pad.name = pad_name
84 self.fn_parameters.append(pad)
85
86
87 if self.image.height == None:
88 self.image.height = "height"
89
90 if self.image.img_yoff == None:
91 self.image.img_yoff = "yoffset"
92
93 if func.image.depth:
94 if self.image.extent == None:
95 self.image.extent = "extent"
96
97 if self.image.img_woff == None:
98 self.image.img_woff = "woffset"
99
100
101 self.set_return_type( func.fn_return_type )
102 self.glx_rop = ~0
103 self.can_be_large = func.can_be_large
104 self.count_parameter_list = func.count_parameter_list
105 self.counter = func.counter
106 self.img_reset = None
107 return
108
109
110 class PrintGlxProtoStubs(glX_XML.GlxProto):
111 def __init__(self):
112 glX_XML.GlxProto.__init__(self)
113 self.last_category = ""
114 self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004, 2005", "IBM")
115 self.generic_sizes = [3, 4, 6, 8, 12, 16, 24, 32]
116 self.pixel_stubs = {}
117 self.debug = 0
118 return
119
120 def printRealHeader(self):
121 print ''
122 print '#include <GL/gl.h>'
123 print '#include "indirect.h"'
124 print '#include "glxclient.h"'
125 print '#include "indirect_size.h"'
126 print '#include <GL/glxproto.h>'
127 print ''
128 print '#define __GLX_PAD(n) (((n) + 3) & ~3)'
129 print ''
130 self.printFastcall()
131 self.printNoinline()
132 print ''
133 print '#if !defined __GNUC__ || __GNUC__ < 3'
134 print '# define __builtin_expect(x, y) x'
135 print '#endif'
136 print ''
137 print '/* If the size and opcode values are known at compile-time, this will, on'
138 print ' * x86 at least, emit them with a single instruction.'
139 print ' */'
140 print '#define emit_header(dest, op, size) \\'
141 print ' do { union { short s[2]; int i; } temp; \\'
142 print ' temp.s[0] = (size); temp.s[1] = (op); \\'
143 print ' *((int *)(dest)) = temp.i; } while(0)'
144 print ''
145 print """NOINLINE CARD32
146 __glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array )
147 {
148 xGLXSingleReply reply;
149
150 (void) _XReply(dpy, (xReply *) & reply, 0, False);
151 if (size != 0) {
152 if ((reply.length > 0) || reply_is_always_array) {
153 const GLint bytes = (reply_is_always_array)
154 ? (4 * reply.length) : (reply.size * size);
155 const GLint extra = 4 - (bytes & 3);
156
157 _XRead(dpy, dest, bytes);
158 if ( extra < 4 ) {
159 _XEatData(dpy, extra);
160 }
161 }
162 else {
163 (void) memcpy( dest, &(reply.pad3), size);
164 }
165 }
166
167 return reply.retval;
168 }
169
170 NOINLINE void
171 __glXReadPixelReply( Display *dpy, __GLXcontext * gc, unsigned max_dim,
172 GLint width, GLint height, GLint depth, GLenum format, GLenum type,
173 void * dest, GLboolean dimensions_in_reply )
174 {
175 xGLXSingleReply reply;
176 GLint size;
177
178 (void) _XReply(dpy, (xReply *) & reply, 0, False);
179
180 if ( dimensions_in_reply ) {
181 width = reply.pad3;
182 height = reply.pad4;
183 depth = reply.pad5;
184
185 if ((height == 0) || (max_dim < 2)) { height = 1; }
186 if ((depth == 0) || (max_dim < 3)) { depth = 1; }
187 }
188
189 size = reply.length * 4;
190 if (size != 0) {
191 void * buf = Xmalloc( size );
192
193 if ( buf == NULL ) {
194 _XEatData(dpy, size);
195 __glXSetError(gc, GL_OUT_OF_MEMORY);
196 }
197 else {
198 const GLint extra = 4 - (size & 3);
199
200 _XRead(dpy, buf, size);
201 if ( extra < 4 ) {
202 _XEatData(dpy, extra);
203 }
204
205 __glEmptyImage(gc, 3, width, height, depth, format, type,
206 buf, dest);
207 Xfree(buf);
208 }
209 }
210 }
211
212 #define X_GLXSingle 0
213
214 NOINLINE FASTCALL GLubyte *
215 __glXSetupSingleRequest( __GLXcontext * gc, GLint sop, GLint cmdlen )
216 {
217 xGLXSingleReq * req;
218 Display * const dpy = gc->currentDpy;
219
220 (void) __glXFlushRenderBuffer(gc, gc->pc);
221 LockDisplay(dpy);
222 GetReqExtra(GLXSingle, cmdlen, req);
223 req->reqType = gc->majorOpcode;
224 req->contextTag = gc->currentContextTag;
225 req->glxCode = sop;
226 return (GLubyte *)(req) + sz_xGLXSingleReq;
227 }
228
229 NOINLINE FASTCALL GLubyte *
230 __glXSetupVendorRequest( __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen )
231 {
232 xGLXVendorPrivateReq * req;
233 Display * const dpy = gc->currentDpy;
234
235 (void) __glXFlushRenderBuffer(gc, gc->pc);
236 LockDisplay(dpy);
237 GetReqExtra(GLXVendorPrivate, cmdlen, req);
238 req->reqType = gc->majorOpcode;
239 req->glxCode = code;
240 req->vendorCode = vop;
241 req->contextTag = gc->currentContextTag;
242 return (GLubyte *)(req) + sz_xGLXVendorPrivateReq;
243 }
244
245 const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 };
246
247 #define zero (__glXDefaultPixelStore+0)
248 #define one (__glXDefaultPixelStore+8)
249 #define default_pixel_store_1D (__glXDefaultPixelStore+4)
250 #define default_pixel_store_1D_size 20
251 #define default_pixel_store_2D (__glXDefaultPixelStore+4)
252 #define default_pixel_store_2D_size 20
253 #define default_pixel_store_3D (__glXDefaultPixelStore+0)
254 #define default_pixel_store_3D_size 36
255 #define default_pixel_store_4D (__glXDefaultPixelStore+0)
256 #define default_pixel_store_4D_size 36
257 """
258
259 for size in self.generic_sizes:
260 self.print_generic_function(size)
261 return
262
263 def printFunction(self, f):
264 if f.client_handcode: return
265
266 if f.glx_rop != 0 or f.vectorequiv != None:
267 if f.image:
268 self.printPixelFunction(f)
269 else:
270 self.printRenderFunction(f)
271 elif f.glx_sop != 0 or f.glx_vendorpriv != 0:
272 self.printSingleFunction(f)
273 else:
274 print "/* Missing GLX protocol for %s. */" % (f.name)
275
276 def print_generic_function(self, n):
277 size = (n + 3) & ~3
278 print """static FASTCALL NOINLINE void
279 generic_%u_byte( GLint rop, const void * ptr )
280 {
281 __GLXcontext * const gc = __glXGetCurrentContext();
282 const GLuint cmdlen = %u;
283
284 emit_header(gc->pc, rop, cmdlen);
285 (void) memcpy((void *)(gc->pc + 4), ptr, %u);
286 gc->pc += cmdlen;
287 if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }
288 }
289 """ % (n, size + 4, size)
290
291
292 def common_emit_one_arg(self, p, offset, pc, indent, adjust):
293 t = p.p_type
294 if p.is_array():
295 src_ptr = p.name
296 else:
297 src_ptr = "&" + p.name
298
299 print '%s (void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
300 % (indent, pc, offset + adjust, src_ptr, p.size_string() )
301
302 def common_emit_args(self, f, pc, indent, adjust, skip_vla):
303 offset = 0
304
305 if skip_vla:
306 r = 1
307 else:
308 r = 2
309
310 for p in f.parameterIterator(1, r):
311 if p.name != f.img_reset:
312 self.common_emit_one_arg(p, offset, pc, indent, adjust)
313 offset += p.size()
314
315 return offset
316
317
318 def pixel_emit_args(self, f, pc, indent, adjust, dim, large):
319 """Emit the arguments for a pixel function. This differs from
320 common_emit_args in that pixel functions may require padding
321 be inserted (i.e., for the missing width field for
322 TexImage1D), and they may also require a 'NULL image' flag
323 be inserted before the image data."""
324
325 offset = 0
326 for p in f.parameterIterator(1, 1):
327 self.common_emit_one_arg(p, offset, pc, indent, adjust)
328 offset += p.size()
329
330 if f.pad_after(p):
331 print '%s (void) memcpy((void *)(%s + %u), zero, 4);' % (indent, pc, offset + adjust)
332 offset += 4
333
334 if f.image.img_null_flag:
335 if large:
336 print '%s (void) memcpy((void *)(%s + %u), zero, 4);' % (indent, pc, offset + adjust)
337 else:
338 print '%s (void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (indent, pc, offset + adjust, f.image.name)
339
340 offset += 4
341
342 return offset
343
344
345 def large_emit_begin(self, indent, f, op_name = None):
346 if not op_name:
347 op_name = f.opcode_real_name()
348
349 print '%s const GLint op = %s;' % (indent, op_name)
350 print '%s const GLuint cmdlenLarge = cmdlen + 4;' % (indent)
351 print '%s GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);' % (indent)
352 print '%s (void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);' % (indent)
353 print '%s (void) memcpy((void *)(pc + 4), (void *)(&op), 4);' % (indent)
354 return
355
356
357 def common_func_print_just_header(self, f):
358 print '#define %s %d' % (f.opcode_name(), f.opcode_value())
359
360 print '%s' % (f.fn_return_type)
361 print '__indirect_gl%s(%s)' % (f.name, f.get_parameter_string())
362 print '{'
363
364
365 def common_func_print_just_start(self, f):
366 print ' __GLXcontext * const gc = __glXGetCurrentContext();'
367
368 # The only reason that single and vendor private commands need
369 # a variable called 'dpy' is becuase they use the SyncHandle
370 # macro. For whatever brain-dead reason, that macro is hard-
371 # coded to use a variable called 'dpy' instead of taking a
372 # parameter.
373
374 if not f.glx_rop:
375 if f.image and f.image.is_output:
376 print ' const __GLXattribute * const state = gc->client_state_private;'
377
378 print ' Display * const dpy = gc->currentDpy;'
379 skip_condition = "dpy != NULL"
380 elif f.can_be_large:
381 skip_condition = "gc->currentDpy != NULL"
382 else:
383 skip_condition = None
384
385
386 if f.fn_return_type != 'void':
387 print ' %s retval = (%s) 0;' % (f.fn_return_type, f.fn_return_type)
388
389 if not f.output_parameter():
390 compsize = self.size_call( f )
391 if compsize:
392 print ' const GLuint compsize = %s;' % (compsize)
393
394 print ' const GLuint cmdlen = %s;' % (f.command_length())
395
396 if f.counter:
397 if skip_condition:
398 skip_condition = "(%s >= 0) && (%s)" % (f.counter, skip_condition)
399 else:
400 skip_condition = "%s >= 0" % (f.counter)
401
402
403 if skip_condition:
404 print ' if (__builtin_expect(%s, 1)) {' % (skip_condition)
405 return 1
406 else:
407 return 0
408
409
410 def common_func_print_header(self, f):
411 self.common_func_print_just_header(f)
412 return self.common_func_print_just_start(f)
413
414
415
416 def printSingleFunction(self, f):
417 self.common_func_print_header(f)
418
419 if self.debug:
420 print ' printf( "Enter %%s...\\n", "gl%s" );' % (f.name)
421
422 if f.fn_parameters != []:
423 pc_decl = "GLubyte const * pc ="
424 else:
425 pc_decl = "(void)"
426
427 if f.glx_vendorpriv != 0:
428 print ' %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl, f.opcode_real_name(), f.opcode_name())
429 else:
430 print ' %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl, f.opcode_name())
431
432 self.common_emit_args(f, "pc", " ", 0, 0)
433 if f.image and f.image.is_output:
434 o = f.command_fixed_length() - 4
435 print ' *(int32_t *)(pc + %u) = 0;' % (o)
436 if f.image.img_format != "GL_COLOR_INDEX" or f.image.img_type != "GL_BITMAP":
437 print ' * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o)
438
439 if f.img_reset:
440 print ' * (int8_t *)(pc + %u) = %s;' % (o + 1, f.img_reset)
441
442
443 if f.needs_reply():
444 if f.image and f.image.is_output:
445 [dim, w, h, d, junk] = f.dimensions()
446 if f.dimensions_in_reply:
447 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)
448 else:
449 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)
450 else:
451 if f.output != None:
452 if f.output.p_type.size == 0:
453 output_size = 1
454 else:
455 output_size = f.output.p_type.size
456
457 output_str = f.output.name
458 else:
459 output_size = 0
460 output_str = "NULL"
461
462 if f.fn_return_type != 'void':
463 return_str = " retval = (%s)" % (f.fn_return_type)
464 else:
465 return_str = " (void)"
466
467 if f.reply_always_array:
468 aa = "GL_TRUE"
469 else:
470 aa = "GL_FALSE"
471
472 print " %s __glXReadReply(dpy, %s, %s, %s);" % (return_str, output_size, output_str, aa)
473
474 elif self.debug:
475 # Only emit the extra glFinish call for functions
476 # that don't already require a reply from the server.
477 print ' __indirect_glFinish();'
478
479 if self.debug:
480 print ' printf( "Exit %%s.\\n", "gl%s" );' % (f.name)
481
482
483 print ' UnlockDisplay(dpy); SyncHandle();'
484 print ' }'
485 print ' %s' % f.return_string()
486 print '}'
487 print ''
488 return
489
490
491 def printPixelFunction(self, f):
492 """This function could use some major refactoring. :("""
493
494 # There is a code-space optimization that we can do here.
495 # Functions that are marked img_pad_dimensions have a version
496 # with an odd number of dimensions and an even number of
497 # dimensions. TexSubImage1D and TexSubImage2D are examples.
498 # We can emit a single function that does both, and have the
499 # real functions call the utility function with the correct
500 # parameters.
501 #
502 # The only quirk to this is that utility funcitons will be
503 # generated for 3D and 4D functions, but 4D (e.g.,
504 # GL_SGIS_texture4D) isn't typically supported. This is
505 # probably not an issue. However, it would be possible to
506 # look at the total set of functions and determine if there
507 # is another function that would actually use the utility
508 # function. If not, then fallback to the normal way of
509 # generating code.
510
511 if f.image.img_pad_dimensions:
512 # Determine the hash key and the name for the utility
513 # function that is used to implement the real
514 # function.
515
516 [h, n] = hash_pixel_function(f)
517
518
519 # If the utility function is not yet known, generate
520 # it.
521
522 if not self.pixel_stubs.has_key(h):
523 self.pixel_stubs[h] = n
524 pixel_func = glXPixelFunctionUtility(f, n)
525
526 print 'static void'
527 print '%s( unsigned opcode, unsigned dim, %s )' % (n, pixel_func.get_parameter_string())
528 print '{'
529
530 if self.common_func_print_just_start(pixel_func):
531 indent = " "
532 trailer = " }"
533 else:
534 indent = ""
535 trailer = None
536
537
538 if pixel_func.can_be_large:
539 print '%s if (cmdlen <= gc->maxSmallRenderCommandSize) {' % (indent)
540 print '%s if ( (gc->pc + cmdlen) > gc->bufEnd ) {' % (indent)
541 print '%s (void) __glXFlushRenderBuffer(gc, gc->pc);' % (indent)
542 print '%s }' % (indent)
543 indent += " "
544
545 [dim, width, height, depth, extent] = pixel_func.dimensions()
546 adjust = pixel_func.offset_of_first_parameter() + 4
547
548 print '%s emit_header(gc->pc, opcode, cmdlen);' % (indent)
549
550 offset = self.pixel_emit_args(pixel_func, "gc->pc", indent, adjust, dim, 0)
551
552 s = pixel_func.command_fixed_length()
553
554 pixHeaderPtr = "gc->pc + 4"
555 pcPtr = "gc->pc + %u" % (s + 4)
556
557 if pixel_func.image.img_send_null:
558 condition = '(compsize > 0) && (%s != NULL)' % (pixel_func.image.name)
559 else:
560 condition = 'compsize > 0'
561
562 print '%s if (%s) {' % (indent, condition)
563 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)
564 print '%s }' % (indent)
565 print '%s else {' % (indent)
566 print '%s (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (indent, pixHeaderPtr, dim, dim)
567 print '%s }' % (indent)
568
569 print '%s gc->pc += cmdlen;' % (indent)
570 print '%s if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent)
571
572 if f.can_be_large:
573 adjust += 4
574
575 print '%s}' % (indent)
576 print '%selse {' % (indent)
577
578 self.large_emit_begin(indent, pixel_func, "opcode")
579 offset = self.pixel_emit_args(pixel_func, "pc", indent, adjust, dim, 1)
580
581 pixHeaderPtr = "pc + 8"
582 pcPtr = "pc + %u" % (s + 8)
583
584 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)
585
586 print '%s}' % (indent)
587
588 if trailer: print trailer
589 print '}'
590 print ''
591
592
593
594 # Generate the real function as a call to the
595 # utility function.
596
597 self.common_func_print_just_header(f)
598
599 [dim, junk, junk, junk, junk] = f.dimensions()
600
601 p_string = ""
602 for p in gl_XML.glFunction.parameterIterator(f):
603 p_string += ", " + p.name
604
605 if f.pad_after(p):
606 p_string += ", 1"
607
608 print ' %s(%s, %u%s );' % (n, f.opcode_name(), dim, p_string)
609 print '}'
610 print ''
611 return
612
613
614 if self.common_func_print_header(f):
615 indent = " "
616 trailer = " }"
617 else:
618 indent = ""
619 trailer = None
620
621
622 if f.can_be_large:
623 print '%s if (cmdlen <= gc->maxSmallRenderCommandSize) {' % (indent)
624 print '%s if ( (gc->pc + cmdlen) > gc->bufEnd ) {' % (indent)
625 print '%s (void) __glXFlushRenderBuffer(gc, gc->pc);' % (indent)
626 print '%s }' % (indent)
627 indent += " "
628
629 [dim, width, height, depth, extent] = f.dimensions()
630 adjust = f.offset_of_first_parameter() + 4
631
632 print '%s emit_header(gc->pc, %s, cmdlen);' % (indent, f.opcode_real_name())
633
634 offset = self.pixel_emit_args(f, "gc->pc", indent, adjust, dim, 0)
635
636 s = f.command_fixed_length()
637
638 pixHeaderPtr = "gc->pc + 4"
639 pcPtr = "gc->pc + %u" % (s + 4)
640
641 if f.image.img_send_null:
642 condition = '(compsize > 0) && (%s != NULL)' % (f.image.name)
643 else:
644 condition = 'compsize > 0'
645
646 print '%s if (%s) {' % (indent, condition)
647 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)
648 print '%s }' % (indent)
649 print '%s else {' % (indent)
650 print '%s (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (indent, pixHeaderPtr, dim, dim)
651 print '%s }' % (indent)
652
653 print '%s gc->pc += cmdlen;' % (indent)
654 print '%s if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent)
655
656 if f.can_be_large:
657 adjust += 4
658
659 print '%s}' % (indent)
660 print '%selse {' % (indent)
661
662 self.large_emit_begin(indent, f)
663 offset = self.pixel_emit_args(f, "pc", indent, adjust, dim, 1)
664
665 pixHeaderPtr = "pc + 8"
666 pcPtr = "pc + %u" % (s + 8)
667
668 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)
669
670 print '%s}' % (indent)
671
672 if trailer: print trailer
673 print '}'
674 print ''
675 return
676
677
678 def printRenderFunction(self, f):
679 # There is a class of GL functions that take a single pointer
680 # as a parameter. This pointer points to a fixed-size chunk
681 # of data, and the protocol for this functions is very
682 # regular. Since they are so regular and there are so many
683 # of them, special case them with generic functions. On
684 # x86, this saves about 26KB in the libGL.so binary.
685
686 if f.variable_length_parameter() == None and len(f.fn_parameters) == 1:
687 p = f.fn_parameters[0]
688 if p.is_pointer:
689 cmdlen = f.command_fixed_length()
690 if cmdlen in self.generic_sizes:
691 self.common_func_print_just_header(f)
692 print ' generic_%u_byte( %s, %s );' % (cmdlen, f.opcode_real_name(), p.name)
693 print '}'
694 print ''
695 return
696
697 if self.common_func_print_header(f):
698 indent = " "
699 trailer = " }"
700 else:
701 indent = ""
702 trailer = None
703
704 if self.debug:
705 print '%s printf( "Enter %%s...\\n", "gl%s" );' % (indent, f.name)
706
707 if f.can_be_large:
708 print '%s if (cmdlen <= gc->maxSmallRenderCommandSize) {' % (indent)
709 print '%s if ( (gc->pc + cmdlen) > gc->bufEnd ) {' % (indent)
710 print '%s (void) __glXFlushRenderBuffer(gc, gc->pc);' % (indent)
711 print '%s }' % (indent)
712 indent += " "
713
714 print '%s emit_header(gc->pc, %s, cmdlen);' % (indent, f.opcode_real_name())
715
716 self.common_emit_args(f, "gc->pc", indent, 4, 0)
717 print '%s gc->pc += cmdlen;' % (indent)
718 print '%s if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent)
719
720 if f.can_be_large:
721 print '%s}' % (indent)
722 print '%selse {' % (indent)
723
724 self.large_emit_begin(indent, f)
725 offset = self.common_emit_args(f, "pc", indent, 8, 1)
726
727 p = f.variable_length_parameter()
728 print '%s __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (indent, offset + 8, p.name, p.size_string())
729 print '%s}' % (indent)
730
731 if self.debug:
732 print '%s __indirect_glFinish();' % (indent)
733 print '%s printf( "Exit %%s.\\n", "gl%s" );' % (indent, f.name)
734
735 if trailer: print trailer
736 print '}'
737 print ''
738 return
739
740
741 class PrintGlxProtoInit_c(glX_XML.GlxProto):
742 def __init__(self):
743 glX_XML.GlxProto.__init__(self)
744 self.last_category = ""
745 self.license = license.bsd_license_template % ( \
746 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
747 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
748
749
750 def printRealHeader(self):
751 print """/**
752 * \\file indirect_init.c
753 * Initialize indirect rendering dispatch table.
754 *
755 * \\author Kevin E. Martin <kevin@precisioninsight.com>
756 * \\author Brian Paul <brian@precisioninsight.com>
757 * \\author Ian Romanick <idr@us.ibm.com>
758 */
759
760 #include "indirect_init.h"
761 #include "indirect.h"
762 #include "glapi.h"
763
764
765 /**
766 * No-op function used to initialize functions that have no GLX protocol
767 * support.
768 */
769 static int NoOp(void)
770 {
771 return 0;
772 }
773
774 /**
775 * Create and initialize a new GL dispatch table. The table is initialized
776 * with GLX indirect rendering protocol functions.
777 */
778 __GLapi * __glXNewIndirectAPI( void )
779 {
780 __GLapi *glAPI;
781 GLuint entries;
782
783 entries = _glapi_get_dispatch_table_size();
784 glAPI = (__GLapi *) Xmalloc(entries * sizeof(void *));
785
786 /* first, set all entries to point to no-op functions */
787 {
788 int i;
789 void **dispatch = (void **) glAPI;
790 for (i = 0; i < entries; i++) {
791 dispatch[i] = (void *) NoOp;
792 }
793 }
794
795 /* now, initialize the entries we understand */"""
796
797 def printRealFooter(self):
798 print """
799 return glAPI;
800 }
801 """
802
803 def printFunction(self, f):
804 if f.category != self.last_category:
805 self.last_category = f.category
806 print ''
807 print ' /* %s */' % (self.last_category)
808 print ''
809
810 print ' glAPI->%s = __indirect_gl%s;' % (f.name, f.name)
811
812
813 class PrintGlxProtoInit_h(glX_XML.GlxProto):
814 def __init__(self):
815 glX_XML.GlxProto.__init__(self)
816 self.last_category = ""
817 self.license = license.bsd_license_template % ( \
818 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
819 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
820 self.header_tag = "_INDIRECT_H_"
821
822 def printRealHeader(self):
823 print """/**
824 * \\file
825 * Prototypes for indirect rendering functions.
826 *
827 * \\author Kevin E. Martin <kevin@precisioninsight.com>
828 * \\author Ian Romanick <idr@us.ibm.com>
829 */
830 """
831 self.printVisibility( "HIDDEN", "hidden" )
832 self.printFastcall()
833 self.printNoinline()
834
835 print """
836 #include "glxclient.h"
837
838 extern HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
839 void * dest, GLboolean reply_is_always_array );
840
841 extern HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
842 __GLXcontext * gc, unsigned max_dim, GLint width, GLint height,
843 GLint depth, GLenum format, GLenum type, void * dest,
844 GLboolean dimensions_in_reply );
845
846 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
847 __GLXcontext * gc, GLint sop, GLint cmdlen );
848
849 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
850 __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen );
851 """
852
853
854 def printFunction(self, f):
855 print 'extern HIDDEN %s __indirect_gl%s(%s);' % (f.fn_return_type, f.name, f.get_parameter_string())
856
857
858 def show_usage():
859 print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys.argv[0]
860 print " -m output_mode Output mode can be one of 'proto', 'init_c' or 'init_h'."
861 print " -d Enable extra debug information in the generated code."
862 sys.exit(1)
863
864
865 if __name__ == '__main__':
866 file_name = "gl_API.xml"
867
868 try:
869 (args, trail) = getopt.getopt(sys.argv[1:], "f:m:d")
870 except Exception,e:
871 show_usage()
872
873 debug = 0
874 mode = "proto"
875 for (arg,val) in args:
876 if arg == "-f":
877 file_name = val
878 elif arg == "-m":
879 mode = val
880 elif arg == "-d":
881 debug = 1
882
883 if mode == "proto":
884 dh = PrintGlxProtoStubs()
885 elif mode == "init_c":
886 dh = PrintGlxProtoInit_c()
887 elif mode == "init_h":
888 dh = PrintGlxProtoInit_h()
889 else:
890 show_usage()
891
892 parser = make_parser()
893 parser.setFeature(feature_namespaces, 1)
894 parser.setContentHandler(dh)
895
896 f = open(file_name)
897
898 dh.debug = debug
899 dh.printHeader()
900 parser.parse(f)
901 dh.printFooter()