f1329d5760fbf1013980039cd665763df9929973
[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 adjust = pixel_func.offset_of_first_parameter() + 4
474
475 print '%s emit_header(gc->pc, opcode, cmdlen);' % (indent)
476
477 offset = self.pixel_emit_args(pixel_func, "gc->pc", indent, adjust, dim, 0)
478
479 s = pixel_func.command_fixed_length()
480
481 pixHeaderPtr = "gc->pc + 4"
482 pcPtr = "gc->pc + %u" % (s + 4)
483
484 if pixel_func.image.img_send_null:
485 condition = '(compsize > 0) && (%s != NULL)' % (pixel_func.image.name)
486 else:
487 condition = 'compsize > 0'
488
489 print '%s if (%s) {' % (indent, condition)
490 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)
491 print '%s }' % (indent)
492 print '%s else {' % (indent)
493 print '%s (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (indent, pixHeaderPtr, dim, dim)
494 print '%s }' % (indent)
495
496 print '%s gc->pc += cmdlen;' % (indent)
497 print '%s if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent)
498
499 if f.can_be_large:
500 adjust += 4
501
502 print '%s}' % (indent)
503 print '%selse {' % (indent)
504
505 self.large_emit_begin(indent, pixel_func, "opcode")
506 offset = self.pixel_emit_args(pixel_func, "pc", indent, adjust, dim, 1)
507
508 pixHeaderPtr = "pc + 8"
509 pcPtr = "pc + %u" % (s + 8)
510
511 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)
512
513 print '%s}' % (indent)
514
515 if trailer: print trailer
516 print '}'
517 print ''
518
519
520
521 # Generate the real function as a call to the
522 # utility function.
523
524 self.common_func_print_just_header(f)
525
526 [dim, junk, junk, junk, junk] = f.dimensions()
527
528 p_string = ""
529 for p in gl_XML.glFunction.parameterIterator(f):
530 p_string += ", " + p.name
531
532 if f.pad_after(p):
533 p_string += ", 1"
534
535 print ' %s(%s, %u%s );' % (n, f.opcode_name(), dim, p_string)
536 print '}'
537 print ''
538 return
539
540
541 if self.common_func_print_header(f):
542 indent = " "
543 trailer = " }"
544 else:
545 indent = ""
546 trailer = None
547
548
549 if f.can_be_large:
550 print '%s if (cmdlen <= gc->maxSmallRenderCommandSize) {' % (indent)
551 print '%s if ( (gc->pc + cmdlen) > gc->bufEnd ) {' % (indent)
552 print '%s (void) __glXFlushRenderBuffer(gc, gc->pc);' % (indent)
553 print '%s }' % (indent)
554 indent += " "
555
556 [dim, width, height, depth, extent] = f.dimensions()
557 adjust = f.offset_of_first_parameter() + 4
558
559 print '%s emit_header(gc->pc, %s, cmdlen);' % (indent, f.opcode_real_name())
560
561 offset = self.pixel_emit_args(f, "gc->pc", indent, adjust, dim, 0)
562
563 s = f.command_fixed_length()
564
565 pixHeaderPtr = "gc->pc + 4"
566 pcPtr = "gc->pc + %u" % (s + 4)
567
568 if f.image.img_send_null:
569 condition = '(compsize > 0) && (%s != NULL)' % (f.image.name)
570 else:
571 condition = 'compsize > 0'
572
573 print '%s if (%s) {' % (indent, condition)
574 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)
575 print '%s }' % (indent)
576 print '%s else {' % (indent)
577 print '%s (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (indent, pixHeaderPtr, dim, dim)
578 print '%s }' % (indent)
579
580 print '%s gc->pc += cmdlen;' % (indent)
581 print '%s if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent)
582
583 if f.can_be_large:
584 adjust += 4
585
586 print '%s}' % (indent)
587 print '%selse {' % (indent)
588
589 self.large_emit_begin(indent, f)
590 offset = self.pixel_emit_args(f, "pc", indent, adjust, dim, 1)
591
592 pixHeaderPtr = "pc + 8"
593 pcPtr = "pc + %u" % (s + 8)
594
595 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)
596
597 print '%s}' % (indent)
598
599 if trailer: print trailer
600 print '}'
601 print ''
602 return
603
604
605 def printRenderFunction(self, f):
606 # There is a class of GL functions that take a single pointer
607 # as a parameter. This pointer points to a fixed-size chunk
608 # of data, and the protocol for this functions is very
609 # regular. Since they are so regular and there are so many
610 # of them, special case them with generic functions. On
611 # x86, this saves about 26KB in the libGL.so binary.
612
613 if f.variable_length_parameter() == None and len(f.fn_parameters) == 1:
614 p = f.fn_parameters[0]
615 if p.is_pointer:
616 cmdlen = f.command_fixed_length()
617 if cmdlen in self.generic_sizes:
618 self.common_func_print_just_header(f)
619 print ' generic_%u_byte( %s, %s );' % (cmdlen, f.opcode_real_name(), p.name)
620 print '}'
621 print ''
622 return
623
624 if self.common_func_print_header(f):
625 indent = " "
626 trailer = " }"
627 else:
628 indent = ""
629 trailer = None
630
631 if f.can_be_large:
632 print '%s if (cmdlen <= gc->maxSmallRenderCommandSize) {' % (indent)
633 print '%s if ( (gc->pc + cmdlen) > gc->bufEnd ) {' % (indent)
634 print '%s (void) __glXFlushRenderBuffer(gc, gc->pc);' % (indent)
635 print '%s }' % (indent)
636 indent += " "
637
638 print '%s emit_header(gc->pc, %s, cmdlen);' % (indent, f.opcode_real_name())
639
640 self.common_emit_args(f, "gc->pc", indent, 4, 0)
641 print '%s gc->pc += cmdlen;' % (indent)
642 print '%s if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent)
643
644 if f.can_be_large:
645 print '%s}' % (indent)
646 print '%selse {' % (indent)
647
648 self.large_emit_begin(indent, f)
649 offset = self.common_emit_args(f, "pc", indent, 8, 1)
650
651 p = f.variable_length_parameter()
652 print '%s __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (indent, offset + 8, p.name, p.size_string())
653 print '%s}' % (indent)
654
655 if trailer: print trailer
656 print '}'
657 print ''
658 return
659
660
661 class PrintGlxProtoInit_c(glX_XML.GlxProto):
662 def __init__(self):
663 glX_XML.GlxProto.__init__(self)
664 self.last_category = ""
665 self.license = license.bsd_license_template % ( \
666 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
667 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
668
669
670 def printRealHeader(self):
671 print """/**
672 * \\file indirect_init.c
673 * Initialize indirect rendering dispatch table.
674 *
675 * \\author Kevin E. Martin <kevin@precisioninsight.com>
676 * \\author Brian Paul <brian@precisioninsight.com>
677 * \\author Ian Romanick <idr@us.ibm.com>
678 */
679
680 #include "indirect_init.h"
681 #include "indirect.h"
682 #include "glapi.h"
683
684
685 /**
686 * No-op function used to initialize functions that have no GLX protocol
687 * support.
688 */
689 static int NoOp(void)
690 {
691 return 0;
692 }
693
694 /**
695 * Create and initialize a new GL dispatch table. The table is initialized
696 * with GLX indirect rendering protocol functions.
697 */
698 __GLapi * __glXNewIndirectAPI( void )
699 {
700 __GLapi *glAPI;
701 GLuint entries;
702
703 entries = _glapi_get_dispatch_table_size();
704 glAPI = (__GLapi *) Xmalloc(entries * sizeof(void *));
705
706 /* first, set all entries to point to no-op functions */
707 {
708 int i;
709 void **dispatch = (void **) glAPI;
710 for (i = 0; i < entries; i++) {
711 dispatch[i] = (void *) NoOp;
712 }
713 }
714
715 /* now, initialize the entries we understand */"""
716
717 def printRealFooter(self):
718 print """
719 return glAPI;
720 }
721 """
722
723 def printFunction(self, f):
724 if f.fn_offset < 0 or f.ignore: return
725
726 if f.category != self.last_category:
727 self.last_category = f.category
728 print ''
729 print ' /* %s */' % (self.last_category)
730 print ''
731
732 print ' glAPI->%s = __indirect_gl%s;' % (f.name, f.name)
733
734
735 class PrintGlxProtoInit_h(glX_XML.GlxProto):
736 def __init__(self):
737 glX_XML.GlxProto.__init__(self)
738 self.last_category = ""
739 self.license = license.bsd_license_template % ( \
740 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
741 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
742
743
744 def printRealHeader(self):
745 print """
746 /**
747 * \\file
748 * Prototypes for indirect rendering functions.
749 *
750 * \\author Kevin E. Martin <kevin@precisioninsight.com>
751 * \\author Ian Romanick <idr@us.ibm.com>
752 */
753
754 #if !defined( _INDIRECT_H_ )
755 # define _INDIRECT_H_
756
757 """
758 glX_XML.printVisibility( "HIDDEN", "hidden" )
759
760
761 def printRealFooter(self):
762 print "# undef HIDDEN"
763 print "#endif /* !defined( _INDIRECT_H_ ) */"
764
765 def printFunction(self, f):
766 if f.fn_offset < 0 or f.ignore: return
767 print 'extern HIDDEN %s __indirect_gl%s(%s);' % (f.fn_return_type, f.name, f.get_parameter_string())
768
769
770 def show_usage():
771 print "Usage: %s [-f input_file_name] [-m output_mode]" % sys.argv[0]
772 sys.exit(1)
773
774
775 if __name__ == '__main__':
776 file_name = "gl_API.xml"
777
778 try:
779 (args, trail) = getopt.getopt(sys.argv[1:], "f:m:")
780 except Exception,e:
781 show_usage()
782
783 mode = "proto"
784 for (arg,val) in args:
785 if arg == "-f":
786 file_name = val
787 elif arg == "-m":
788 mode = val
789
790 if mode == "proto":
791 dh = PrintGlxProtoStubs()
792 elif mode == "init_c":
793 dh = PrintGlxProtoInit_c()
794 elif mode == "init_h":
795 dh = PrintGlxProtoInit_h()
796 else:
797 show_usage()
798
799 parser = make_parser()
800 parser.setFeature(feature_namespaces, 0)
801 parser.setContentHandler(dh)
802
803 f = open(file_name)
804
805 dh.printHeader()
806 parser.parse(f)
807 dh.printFooter()