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