Fix some build warnings, mostly with XCB.
[mesa.git] / src / mesa / glapi / glX_proto_send.py
1 #!/usr/bin/env python
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 # Jeremy Kolb <jkolb@brandeis.edu>
28
29 import gl_XML, glX_XML, glX_proto_common, license
30 import sys, getopt, copy, string
31
32 def convertStringForXCB(str):
33 tmp = ""
34 special = [ "ARB" ]
35 i = 0
36 while i < len(str):
37 if str[i:i+3] in special:
38 tmp = '%s_%s' % (tmp, string.lower(str[i:i+3]))
39 i = i + 2;
40 elif str[i].isupper():
41 tmp = '%s_%s' % (tmp, string.lower(str[i]))
42 else:
43 tmp = '%s%s' % (tmp, str[i])
44 i += 1
45 return tmp
46
47 def hash_pixel_function(func):
48 """Generate a 'unique' key for a pixel function. The key is based on
49 the parameters written in the command packet. This includes any
50 padding that might be added for the original function and the 'NULL
51 image' flag."""
52
53
54 h = ""
55 hash_pre = ""
56 hash_suf = ""
57 for param in func.parameterIterateGlxSend():
58 if param.is_image():
59 [dim, junk, junk, junk, junk] = param.get_dimensions()
60
61 d = (dim + 1) & ~1
62 hash_pre = "%uD%uD_" % (d - 1, d)
63
64 if param.img_null_flag:
65 hash_suf = "_NF"
66
67 h += "%u" % (param.size())
68
69 if func.pad_after(param):
70 h += "4"
71
72
73 n = func.name.replace("%uD" % (dim), "")
74 n = "__glx_%s_%uD%uD" % (n, d - 1, d)
75
76 h = hash_pre + h + hash_suf
77 return [h, n]
78
79
80 class glx_pixel_function_stub(glX_XML.glx_function):
81 """Dummy class used to generate pixel "utility" functions that are
82 shared by multiple dimension image functions. For example, these
83 objects are used to generate shared functions used to send GLX
84 protocol for TexImage1D and TexImage2D, TexSubImage1D and
85 TexSubImage2D, etc."""
86
87 def __init__(self, func, name):
88 # The parameters to the utility function are the same as the
89 # parameters to the real function except for the added "pad"
90 # parameters.
91
92 self.name = name
93 self.images = []
94 self.parameters = []
95 self.parameters_by_name = {}
96 for _p in func.parameterIterator():
97 p = copy.copy(_p)
98 self.parameters.append(p)
99 self.parameters_by_name[ p.name ] = p
100
101
102 if p.is_image():
103 self.images.append(p)
104 p.height = "height"
105
106 if p.img_yoff == None:
107 p.img_yoff = "yoffset"
108
109 if p.depth:
110 if p.extent == None:
111 p.extent = "extent"
112
113 if p.img_woff == None:
114 p.img_woff = "woffset"
115
116
117 pad_name = func.pad_after(p)
118 if pad_name:
119 pad = copy.copy(p)
120 pad.name = pad_name
121 self.parameters.append(pad)
122 self.parameters_by_name[ pad.name ] = pad
123
124
125 self.return_type = func.return_type
126
127 self.glx_rop = ~0
128 self.glx_sop = 0
129 self.glx_vendorpriv = 0
130
131 self.glx_doubles_in_order = func.glx_doubles_in_order
132
133 self.vectorequiv = None
134 self.output = None
135 self.can_be_large = func.can_be_large
136 self.reply_always_array = func.reply_always_array
137 self.dimensions_in_reply = func.dimensions_in_reply
138 self.img_reset = None
139
140 self.server_handcode = 0
141 self.client_handcode = 0
142 self.ignore = 0
143
144 self.count_parameter_list = func.count_parameter_list
145 self.counter_list = func.counter_list
146 self.offsets_calculated = 0
147 return
148
149
150 class PrintGlxProtoStubs(glX_proto_common.glx_print_proto):
151 def __init__(self):
152 glX_proto_common.glx_print_proto.__init__(self)
153 self.name = "glX_proto_send.py (from Mesa)"
154 self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004, 2005", "IBM")
155
156
157 self.last_category = ""
158 self.generic_sizes = [3, 4, 6, 8, 12, 16, 24, 32]
159 self.pixel_stubs = {}
160 self.debug = 0
161 return
162
163 def printRealHeader(self):
164 print ''
165 print '#include <GL/gl.h>'
166 print '#include "indirect.h"'
167 print '#include "glxclient.h"'
168 print '#include "indirect_size.h"'
169 print '#include "dispatch.h"'
170 print '#include "glapi.h"'
171 print '#include "glthread.h"'
172 print '#include <GL/glxproto.h>'
173 print '#ifdef USE_XCB'
174 print '#include <X11/Xlib-xcb.h>'
175 print '#include <xcb/xcb.h>'
176 print '#include <xcb/glx.h>'
177 print '#endif /* USE_XCB */'
178
179 print ''
180 print '#define __GLX_PAD(n) (((n) + 3) & ~3)'
181 print ''
182 self.printFastcall()
183 self.printNoinline()
184 print ''
185 print '#if !defined __GNUC__ || __GNUC__ < 3'
186 print '# define __builtin_expect(x, y) x'
187 print '#endif'
188 print ''
189 print '/* If the size and opcode values are known at compile-time, this will, on'
190 print ' * x86 at least, emit them with a single instruction.'
191 print ' */'
192 print '#define emit_header(dest, op, size) \\'
193 print ' do { union { short s[2]; int i; } temp; \\'
194 print ' temp.s[0] = (size); temp.s[1] = (op); \\'
195 print ' *((int *)(dest)) = temp.i; } while(0)'
196 print ''
197 print """NOINLINE CARD32
198 __glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array )
199 {
200 xGLXSingleReply reply;
201
202 (void) _XReply(dpy, (xReply *) & reply, 0, False);
203 if (size != 0) {
204 if ((reply.length > 0) || reply_is_always_array) {
205 const GLint bytes = (reply_is_always_array)
206 ? (4 * reply.length) : (reply.size * size);
207 const GLint extra = 4 - (bytes & 3);
208
209 _XRead(dpy, dest, bytes);
210 if ( extra < 4 ) {
211 _XEatData(dpy, extra);
212 }
213 }
214 else {
215 (void) memcpy( dest, &(reply.pad3), size);
216 }
217 }
218
219 return reply.retval;
220 }
221
222 NOINLINE void
223 __glXReadPixelReply( Display *dpy, __GLXcontext * gc, unsigned max_dim,
224 GLint width, GLint height, GLint depth, GLenum format, GLenum type,
225 void * dest, GLboolean dimensions_in_reply )
226 {
227 xGLXSingleReply reply;
228 GLint size;
229
230 (void) _XReply(dpy, (xReply *) & reply, 0, False);
231
232 if ( dimensions_in_reply ) {
233 width = reply.pad3;
234 height = reply.pad4;
235 depth = reply.pad5;
236
237 if ((height == 0) || (max_dim < 2)) { height = 1; }
238 if ((depth == 0) || (max_dim < 3)) { depth = 1; }
239 }
240
241 size = reply.length * 4;
242 if (size != 0) {
243 void * buf = Xmalloc( size );
244
245 if ( buf == NULL ) {
246 _XEatData(dpy, size);
247 __glXSetError(gc, GL_OUT_OF_MEMORY);
248 }
249 else {
250 const GLint extra = 4 - (size & 3);
251
252 _XRead(dpy, buf, size);
253 if ( extra < 4 ) {
254 _XEatData(dpy, extra);
255 }
256
257 __glEmptyImage(gc, 3, width, height, depth, format, type,
258 buf, dest);
259 Xfree(buf);
260 }
261 }
262 }
263
264 #define X_GLXSingle 0
265
266 NOINLINE FASTCALL GLubyte *
267 __glXSetupSingleRequest( __GLXcontext * gc, GLint sop, GLint cmdlen )
268 {
269 xGLXSingleReq * req;
270 Display * const dpy = gc->currentDpy;
271
272 (void) __glXFlushRenderBuffer(gc, gc->pc);
273 LockDisplay(dpy);
274 GetReqExtra(GLXSingle, cmdlen, req);
275 req->reqType = gc->majorOpcode;
276 req->contextTag = gc->currentContextTag;
277 req->glxCode = sop;
278 return (GLubyte *)(req) + sz_xGLXSingleReq;
279 }
280
281 NOINLINE FASTCALL GLubyte *
282 __glXSetupVendorRequest( __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen )
283 {
284 xGLXVendorPrivateReq * req;
285 Display * const dpy = gc->currentDpy;
286
287 (void) __glXFlushRenderBuffer(gc, gc->pc);
288 LockDisplay(dpy);
289 GetReqExtra(GLXVendorPrivate, cmdlen, req);
290 req->reqType = gc->majorOpcode;
291 req->glxCode = code;
292 req->vendorCode = vop;
293 req->contextTag = gc->currentContextTag;
294 return (GLubyte *)(req) + sz_xGLXVendorPrivateReq;
295 }
296
297 const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 };
298
299 #define zero (__glXDefaultPixelStore+0)
300 #define one (__glXDefaultPixelStore+8)
301 #define default_pixel_store_1D (__glXDefaultPixelStore+4)
302 #define default_pixel_store_1D_size 20
303 #define default_pixel_store_2D (__glXDefaultPixelStore+4)
304 #define default_pixel_store_2D_size 20
305 #define default_pixel_store_3D (__glXDefaultPixelStore+0)
306 #define default_pixel_store_3D_size 36
307 #define default_pixel_store_4D (__glXDefaultPixelStore+0)
308 #define default_pixel_store_4D_size 36
309 """
310
311 for size in self.generic_sizes:
312 self.print_generic_function(size)
313 return
314
315
316 def printBody(self, api):
317
318 self.pixel_stubs = {}
319 generated_stubs = []
320
321 for func in api.functionIterateGlx():
322 if func.client_handcode: continue
323
324 # If the function is a pixel function with a certain
325 # GLX protocol signature, create a fake stub function
326 # for it. For example, create a single stub function
327 # that is used to implement both glTexImage1D and
328 # glTexImage2D.
329
330 if func.glx_rop != 0:
331 do_it = 0
332 for image in func.get_images():
333 if image.img_pad_dimensions:
334 do_it = 1
335 break
336
337
338 if do_it:
339 [h, n] = hash_pixel_function(func)
340
341
342 self.pixel_stubs[ func.name ] = n
343 if h not in generated_stubs:
344 generated_stubs.append(h)
345
346 fake_func = glx_pixel_function_stub( func, n )
347 self.printFunction(fake_func, fake_func.name)
348
349
350 self.printFunction(func, func.name)
351 if func.glx_sop and func.glx_vendorpriv:
352 self.printFunction(func, func.glx_vendorpriv_names[0])
353
354 return
355
356
357 def printFunction(self, func, name):
358 footer = '}\n'
359 if func.glx_rop == ~0:
360 print 'static %s' % (func.return_type)
361 print '%s( unsigned opcode, unsigned dim, %s )' % (func.name, func.get_parameter_string())
362 print '{'
363 else:
364 if func.has_different_protocol(name):
365 if func.return_type == "void":
366 ret_string = ''
367 else:
368 ret_string = "return "
369
370 func_name = func.static_glx_name(name)
371 print '#define %s %d' % (func.opcode_vendor_name(name), func.glx_vendorpriv)
372 print '%s gl%s(%s)' % (func.return_type, func_name, func.get_parameter_string())
373 print '{'
374 print ' __GLXcontext * const gc = __glXGetCurrentContext();'
375 print ''
376 print ' if (gc->isDirect) {'
377 print ' %sCALL_%s(GET_DISPATCH(), (%s));' % (ret_string, func.name, func.get_called_parameter_string())
378 print ' } else {'
379 footer = '}\n}\n'
380 else:
381 print '#define %s %d' % (func.opcode_name(), func.opcode_value())
382
383 print '%s __indirect_gl%s(%s)' % (func.return_type, name, func.get_parameter_string())
384 print '{'
385
386
387 if func.glx_rop != 0 or func.vectorequiv != None:
388 if len(func.images):
389 self.printPixelFunction(func)
390 else:
391 self.printRenderFunction(func)
392 elif func.glx_sop != 0 or func.glx_vendorpriv != 0:
393 self.printSingleFunction(func, name)
394 pass
395 else:
396 print "/* Missing GLX protocol for %s. */" % (name)
397
398 print footer
399 return
400
401
402 def print_generic_function(self, n):
403 size = (n + 3) & ~3
404 print """static FASTCALL NOINLINE void
405 generic_%u_byte( GLint rop, const void * ptr )
406 {
407 __GLXcontext * const gc = __glXGetCurrentContext();
408 const GLuint cmdlen = %u;
409
410 emit_header(gc->pc, rop, cmdlen);
411 (void) memcpy((void *)(gc->pc + 4), ptr, %u);
412 gc->pc += cmdlen;
413 if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }
414 }
415 """ % (n, size + 4, size)
416 return
417
418
419 def common_emit_one_arg(self, p, pc, adjust, extra_offset):
420 if p.is_array():
421 src_ptr = p.name
422 else:
423 src_ptr = "&" + p.name
424
425 if not extra_offset:
426 print '(void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
427 % (pc, p.offset + adjust, src_ptr, p.size_string() )
428 else:
429 print '(void) memcpy((void *)(%s + %u + %s), (void *)(%s), %s);' \
430 % (pc, p.offset + adjust, extra_offset, src_ptr, p.size_string() )
431
432 def common_emit_args(self, f, pc, adjust, skip_vla):
433 extra_offset = None
434
435 for p in f.parameterIterateGlxSend( not skip_vla ):
436 if p.name != f.img_reset:
437 self.common_emit_one_arg(p, pc, adjust, extra_offset)
438
439 if p.is_variable_length():
440 temp = p.size_string()
441 if extra_offset:
442 extra_offset += " + %s" % (temp)
443 else:
444 extra_offset = temp
445
446 return
447
448
449 def pixel_emit_args(self, f, pc, large):
450 """Emit the arguments for a pixel function. This differs from
451 common_emit_args in that pixel functions may require padding
452 be inserted (i.e., for the missing width field for
453 TexImage1D), and they may also require a 'NULL image' flag
454 be inserted before the image data."""
455
456 if large:
457 adjust = 8
458 else:
459 adjust = 4
460
461 for param in f.parameterIterateGlxSend():
462 if not param.is_image():
463 self.common_emit_one_arg(param, pc, adjust, None)
464
465 if f.pad_after(param):
466 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc, (param.offset + param.size()) + adjust)
467
468 else:
469 [dim, width, height, depth, extent] = param.get_dimensions()
470 if f.glx_rop == ~0:
471 dim_str = "dim"
472 else:
473 dim_str = str(dim)
474
475 if param.img_null_flag:
476 if large:
477 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc, (param.offset - 4) + adjust)
478 else:
479 print '(void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (pc, (param.offset - 4) + adjust, param.name)
480
481
482 pixHeaderPtr = "%s + %u" % (pc, adjust)
483 pcPtr = "%s + %u" % (pc, param.offset + adjust)
484
485 if not large:
486 if param.img_send_null:
487 condition = '(compsize > 0) && (%s != NULL)' % (param.name)
488 else:
489 condition = 'compsize > 0'
490
491 print 'if (%s) {' % (condition)
492 print ' (*gc->fillImage)(gc, %s, %s, %s, %s, %s, %s, %s, %s, %s);' % (dim_str, width, height, depth, param.img_format, param.img_type, param.name, pcPtr, pixHeaderPtr)
493 print '} else {'
494 print ' (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (pixHeaderPtr, dim, dim)
495 print '}'
496 else:
497 print '__glXSendLargeImage(gc, compsize, %s, %s, %s, %s, %s, %s, %s, %s, %s);' % (dim_str, width, height, depth, param.img_format, param.img_type, param.name, pcPtr, pixHeaderPtr)
498
499 return
500
501
502 def large_emit_begin(self, f, op_name = None):
503 if not op_name:
504 op_name = f.opcode_real_name()
505
506 print 'const GLint op = %s;' % (op_name)
507 print 'const GLuint cmdlenLarge = cmdlen + 4;'
508 print 'GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);'
509 print '(void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);'
510 print '(void) memcpy((void *)(pc + 4), (void *)(&op), 4);'
511 return
512
513
514 def common_func_print_just_start(self, f, name):
515 print ' __GLXcontext * const gc = __glXGetCurrentContext();'
516
517 # The only reason that single and vendor private commands need
518 # a variable called 'dpy' is becuase they use the SyncHandle
519 # macro. For whatever brain-dead reason, that macro is hard-
520 # coded to use a variable called 'dpy' instead of taking a
521 # parameter.
522
523 # FIXME Simplify the logic related to skip_condition and
524 # FIXME condition_list in this function. Basically, remove
525 # FIXME skip_condition, and just append the "dpy != NULL" type
526 # FIXME condition to condition_list from the start. The only
527 # FIXME reason it's done in this confusing way now is to
528 # FIXME minimize the diffs in the generated code.
529
530 if not f.glx_rop:
531 for p in f.parameterIterateOutputs():
532 if p.is_image() and (p.img_format != "GL_COLOR_INDEX" or p.img_type != "GL_BITMAP"):
533 print ' const __GLXattribute * const state = gc->client_state_private;'
534 break
535
536 print ' Display * const dpy = gc->currentDpy;'
537 skip_condition = "dpy != NULL"
538 elif f.can_be_large:
539 skip_condition = "gc->currentDpy != NULL"
540 else:
541 skip_condition = None
542
543
544 if f.return_type != 'void':
545 print ' %s retval = (%s) 0;' % (f.return_type, f.return_type)
546
547
548 if name != None and name not in f.glx_vendorpriv_names:
549 print '#ifndef USE_XCB'
550 self.emit_packet_size_calculation(f, 0)
551 if name != None and name not in f.glx_vendorpriv_names:
552 print '#endif'
553
554 condition_list = []
555 for p in f.parameterIterateCounters():
556 condition_list.append( "%s >= 0" % (p.name) )
557
558 if skip_condition:
559 condition_list.append( skip_condition )
560
561 if len( condition_list ) > 0:
562 if len( condition_list ) > 1:
563 skip_condition = "(%s)" % (string.join( condition_list, ") && (" ))
564 else:
565 skip_condition = "%s" % (condition_list.pop(0))
566
567 print ' if (__builtin_expect(%s, 1)) {' % (skip_condition)
568 return 1
569 else:
570 return 0
571
572
573 def printSingleFunction(self, f, name):
574 self.common_func_print_just_start(f, name)
575
576 if self.debug:
577 print ' printf( "Enter %%s...\\n", "gl%s" );' % (f.name)
578
579 if name not in f.glx_vendorpriv_names:
580
581 # XCB specific:
582 print '#ifdef USE_XCB'
583 if self.debug:
584 print ' printf("\\tUsing XCB.\\n");'
585 print ' xcb_connection_t *c = XGetXCBConnection(dpy);'
586 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
587 xcb_name = 'xcb_glx%s' % convertStringForXCB(name)
588
589 iparams=[]
590 extra_iparams = []
591 output = None
592 for p in f.parameterIterator():
593 if p.is_output:
594 output = p
595
596 if p.is_image():
597 if p.img_format != "GL_COLOR_INDEX" or p.img_type != "GL_BITMAP":
598 extra_iparams.append("state->storePack.swapEndian")
599 else:
600 extra_iparams.append("0")
601
602 # Hardcode this in. lsb_first param (apparently always GL_FALSE)
603 # also present in GetPolygonStipple, but taken care of above.
604 if xcb_name == "xcb_glx_read_pixels":
605 extra_iparams.append("0")
606 else:
607 iparams.append(p.name)
608
609
610 xcb_request = '%s(%s)' % (xcb_name, ", ".join(["c", "gc->currentContextTag"] + iparams + extra_iparams))
611
612 if f.needs_reply():
613 print ' %s_reply_t *reply = %s_reply(c, %s, NULL);' % (xcb_name, xcb_name, xcb_request)
614 if output and f.reply_always_array:
615 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output.name, xcb_name, xcb_name, output.get_base_type_string())
616
617 elif output and not f.reply_always_array:
618 if not output.is_image():
619 print ' if (%s_data_length(reply) == 0)' % (xcb_name)
620 print ' (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output.name)
621 print ' else'
622 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output.name, xcb_name, xcb_name, output.get_base_type_string())
623
624
625 if f.return_type != 'void':
626 print ' retval = reply->ret_val;'
627 print ' free(reply);'
628 else:
629 print ' ' + xcb_request + ';'
630 print '#else'
631 # End of XCB specific.
632
633
634 if f.parameters != []:
635 pc_decl = "GLubyte const * pc ="
636 else:
637 pc_decl = "(void)"
638
639 if name in f.glx_vendorpriv_names:
640 print ' %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl, f.opcode_real_name(), f.opcode_vendor_name(name))
641 else:
642 print ' %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl, f.opcode_name())
643
644 self.common_emit_args(f, "pc", 0, 0)
645
646 images = f.get_images()
647
648 for img in images:
649 if img.is_output:
650 o = f.command_fixed_length() - 4
651 print ' *(int32_t *)(pc + %u) = 0;' % (o)
652 if img.img_format != "GL_COLOR_INDEX" or img.img_type != "GL_BITMAP":
653 print ' * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o)
654
655 if f.img_reset:
656 print ' * (int8_t *)(pc + %u) = %s;' % (o + 1, f.img_reset)
657
658
659 return_name = ''
660 if f.needs_reply():
661 if f.return_type != 'void':
662 return_name = " retval"
663 return_str = " retval = (%s)" % (f.return_type)
664 else:
665 return_str = " (void)"
666
667 got_reply = 0
668
669 for p in f.parameterIterateOutputs():
670 if p.is_image():
671 [dim, w, h, d, junk] = p.get_dimensions()
672 if f.dimensions_in_reply:
673 print " __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim, p.img_format, p.img_type, p.name)
674 else:
675 print " __glXReadPixelReply(dpy, gc, %u, %s, %s, %s, %s, %s, %s, GL_FALSE);" % (dim, w, h, d, p.img_format, p.img_type, p.name)
676
677 got_reply = 1
678 else:
679 if f.reply_always_array:
680 aa = "GL_TRUE"
681 else:
682 aa = "GL_FALSE"
683
684 # gl_parameter.size() returns the size
685 # of the entire data item. If the
686 # item is a fixed-size array, this is
687 # the size of the whole array. This
688 # is not what __glXReadReply wants. It
689 # wants the size of a single data
690 # element in the reply packet.
691 # Dividing by the array size (1 for
692 # non-arrays) gives us this.
693
694 s = p.size() / p.get_element_count()
695 print " %s __glXReadReply(dpy, %s, %s, %s);" % (return_str, s, p.name, aa)
696 got_reply = 1
697
698
699 # If a reply wasn't read to fill an output parameter,
700 # read a NULL reply to get the return value.
701
702 if not got_reply:
703 print " %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str)
704
705
706 elif self.debug:
707 # Only emit the extra glFinish call for functions
708 # that don't already require a reply from the server.
709 print ' __indirect_glFinish();'
710
711 if self.debug:
712 print ' printf( "Exit %%s.\\n", "gl%s" );' % (name)
713
714
715 print ' UnlockDisplay(dpy); SyncHandle();'
716
717 if name not in f.glx_vendorpriv_names:
718 print '#endif /* USE_XCB */'
719
720 print ' }'
721 print ' return%s;' % (return_name)
722 return
723
724
725 def printPixelFunction(self, f):
726 if self.pixel_stubs.has_key( f.name ):
727 # Normally gl_function::get_parameter_string could be
728 # used. However, this call needs to have the missing
729 # dimensions (e.g., a fake height value for
730 # glTexImage1D) added in.
731
732 p_string = ""
733 for param in f.parameterIterateGlxSend():
734 p_string += ", " + param.name
735
736 if param.is_image():
737 [dim, junk, junk, junk, junk] = param.get_dimensions()
738
739 if f.pad_after(param):
740 p_string += ", 1"
741
742 print ' %s(%s, %u%s );' % (self.pixel_stubs[f.name] , f.opcode_name(), dim, p_string)
743 return
744
745
746 if self.common_func_print_just_start(f, None):
747 trailer = " }"
748 else:
749 trailer = None
750
751
752 if f.can_be_large:
753 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
754 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
755 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
756 print ' }'
757
758 if f.glx_rop == ~0:
759 opcode = "opcode"
760 else:
761 opcode = f.opcode_real_name()
762
763 print 'emit_header(gc->pc, %s, cmdlen);' % (opcode)
764
765 self.pixel_emit_args( f, "gc->pc", 0 )
766 print 'gc->pc += cmdlen;'
767 print 'if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
768
769 if f.can_be_large:
770 print '}'
771 print 'else {'
772
773 self.large_emit_begin(f, opcode)
774 self.pixel_emit_args(f, "pc", 1)
775
776 print '}'
777
778 if trailer: print trailer
779 return
780
781
782 def printRenderFunction(self, f):
783 # There is a class of GL functions that take a single pointer
784 # as a parameter. This pointer points to a fixed-size chunk
785 # of data, and the protocol for this functions is very
786 # regular. Since they are so regular and there are so many
787 # of them, special case them with generic functions. On
788 # x86, this saves about 26KB in the libGL.so binary.
789
790 if f.variable_length_parameter() == None and len(f.parameters) == 1:
791 p = f.parameters[0]
792 if p.is_pointer():
793 cmdlen = f.command_fixed_length()
794 if cmdlen in self.generic_sizes:
795 print ' generic_%u_byte( %s, %s );' % (cmdlen, f.opcode_real_name(), p.name)
796 return
797
798 if self.common_func_print_just_start(f, None):
799 trailer = " }"
800 else:
801 trailer = None
802
803 if self.debug:
804 print 'printf( "Enter %%s...\\n", "gl%s" );' % (f.name)
805
806 if f.can_be_large:
807 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
808 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
809 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
810 print ' }'
811
812 print 'emit_header(gc->pc, %s, cmdlen);' % (f.opcode_real_name())
813
814 self.common_emit_args(f, "gc->pc", 4, 0)
815 print 'gc->pc += cmdlen;'
816 print 'if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
817
818 if f.can_be_large:
819 print '}'
820 print 'else {'
821
822 self.large_emit_begin(f)
823 self.common_emit_args(f, "pc", 8, 1)
824
825 p = f.variable_length_parameter()
826 print ' __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (p.offset + 8, p.name, p.size_string())
827 print '}'
828
829 if self.debug:
830 print '__indirect_glFinish();'
831 print 'printf( "Exit %%s.\\n", "gl%s" );' % (f.name)
832
833 if trailer: print trailer
834 return
835
836
837 class PrintGlxProtoInit_c(gl_XML.gl_print_base):
838 def __init__(self):
839 gl_XML.gl_print_base.__init__(self)
840
841 self.name = "glX_proto_send.py (from Mesa)"
842 self.license = license.bsd_license_template % ( \
843 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
844 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
845 return
846
847
848 def printRealHeader(self):
849 print """/**
850 * \\file indirect_init.c
851 * Initialize indirect rendering dispatch table.
852 *
853 * \\author Kevin E. Martin <kevin@precisioninsight.com>
854 * \\author Brian Paul <brian@precisioninsight.com>
855 * \\author Ian Romanick <idr@us.ibm.com>
856 */
857
858 #include "indirect_init.h"
859 #include "indirect.h"
860 #include "glapi.h"
861
862
863 /**
864 * No-op function used to initialize functions that have no GLX protocol
865 * support.
866 */
867 static int NoOp(void)
868 {
869 return 0;
870 }
871
872 /**
873 * Create and initialize a new GL dispatch table. The table is initialized
874 * with GLX indirect rendering protocol functions.
875 */
876 __GLapi * __glXNewIndirectAPI( void )
877 {
878 __GLapi *glAPI;
879 GLuint entries;
880
881 entries = _glapi_get_dispatch_table_size();
882 glAPI = (__GLapi *) Xmalloc(entries * sizeof(void *));
883
884 /* first, set all entries to point to no-op functions */
885 {
886 int i;
887 void **dispatch = (void **) glAPI;
888 for (i = 0; i < entries; i++) {
889 dispatch[i] = (void *) NoOp;
890 }
891 }
892
893 /* now, initialize the entries we understand */"""
894
895 def printRealFooter(self):
896 print """
897 return glAPI;
898 }
899 """
900 return
901
902
903 def printBody(self, api):
904 for [name, number] in api.categoryIterate():
905 if number != None:
906 preamble = '\n /* %3u. %s */\n\n' % (int(number), name)
907 else:
908 preamble = '\n /* %s */\n\n' % (name)
909
910 for func in api.functionIterateByCategory(name):
911 if func.client_supported_for_indirect():
912 print '%s glAPI->%s = __indirect_gl%s;' % (preamble, func.name, func.name)
913 preamble = ''
914
915 return
916
917
918 class PrintGlxProtoInit_h(gl_XML.gl_print_base):
919 def __init__(self):
920 gl_XML.gl_print_base.__init__(self)
921
922 self.name = "glX_proto_send.py (from Mesa)"
923 self.license = license.bsd_license_template % ( \
924 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
925 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
926 self.header_tag = "_INDIRECT_H_"
927
928 self.last_category = ""
929 return
930
931
932 def printRealHeader(self):
933 print """/**
934 * \\file
935 * Prototypes for indirect rendering functions.
936 *
937 * \\author Kevin E. Martin <kevin@precisioninsight.com>
938 * \\author Ian Romanick <idr@us.ibm.com>
939 */
940 """
941 self.printVisibility( "HIDDEN", "hidden" )
942 self.printFastcall()
943 self.printNoinline()
944
945 print """
946 #include "glxclient.h"
947
948 extern HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
949 void * dest, GLboolean reply_is_always_array );
950
951 extern HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
952 __GLXcontext * gc, unsigned max_dim, GLint width, GLint height,
953 GLint depth, GLenum format, GLenum type, void * dest,
954 GLboolean dimensions_in_reply );
955
956 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
957 __GLXcontext * gc, GLint sop, GLint cmdlen );
958
959 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
960 __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen );
961 """
962
963
964 def printBody(self, api):
965 for func in api.functionIterateGlx():
966 params = func.get_parameter_string()
967
968 print 'extern HIDDEN %s __indirect_gl%s(%s);' % (func.return_type, func.name, params)
969
970 for n in func.entry_points:
971 if func.has_different_protocol(n):
972 asdf = func.static_glx_name(n)
973 if asdf not in func.static_entry_points:
974 print 'extern HIDDEN %s gl%s(%s);' % (func.return_type, asdf, params)
975 else:
976 print 'GLAPI %s GLAPIENTRY gl%s(%s);' % (func.return_type, asdf, params)
977
978 break
979
980
981
982 def show_usage():
983 print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys.argv[0]
984 print " -m output_mode Output mode can be one of 'proto', 'init_c' or 'init_h'."
985 print " -d Enable extra debug information in the generated code."
986 sys.exit(1)
987
988
989 if __name__ == '__main__':
990 file_name = "gl_API.xml"
991
992 try:
993 (args, trail) = getopt.getopt(sys.argv[1:], "f:m:d")
994 except Exception,e:
995 show_usage()
996
997 debug = 0
998 mode = "proto"
999 for (arg,val) in args:
1000 if arg == "-f":
1001 file_name = val
1002 elif arg == "-m":
1003 mode = val
1004 elif arg == "-d":
1005 debug = 1
1006
1007 if mode == "proto":
1008 printer = PrintGlxProtoStubs()
1009 elif mode == "init_c":
1010 printer = PrintGlxProtoInit_c()
1011 elif mode == "init_h":
1012 printer = PrintGlxProtoInit_h()
1013 else:
1014 show_usage()
1015
1016
1017 printer.debug = debug
1018 api = gl_XML.parse_GL_API( file_name, glX_XML.glx_item_factory() )
1019
1020 printer.Print( api )