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