glx: Fix compile warnings since 99fee476a102be898a1a093c037e06382f90a5b9
[mesa.git] / src / mapi / glapi / gen / 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 "glapi.h"'
170 print '#include "glthread.h"'
171 print '#include <GL/glxproto.h>'
172 print '#ifdef USE_XCB'
173 print '#include <X11/Xlib-xcb.h>'
174 print '#include <xcb/xcb.h>'
175 print '#include <xcb/glx.h>'
176 print '#endif /* USE_XCB */'
177
178 print ''
179 print '#define __GLX_PAD(n) (((n) + 3) & ~3)'
180 print ''
181 self.printFastcall()
182 self.printNoinline()
183 print ''
184 print '#ifndef __GNUC__'
185 print '# define __builtin_expect(x, y) x'
186 print '#endif'
187 print ''
188 print '/* If the size and opcode values are known at compile-time, this will, on'
189 print ' * x86 at least, emit them with a single instruction.'
190 print ' */'
191 print '#define emit_header(dest, op, size) \\'
192 print ' do { union { short s[2]; int i; } temp; \\'
193 print ' temp.s[0] = (size); temp.s[1] = (op); \\'
194 print ' *((int *)(dest)) = temp.i; } while(0)'
195 print ''
196 print """NOINLINE CARD32
197 __glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array )
198 {
199 xGLXSingleReply reply;
200
201 (void) _XReply(dpy, (xReply *) & reply, 0, False);
202 if (size != 0) {
203 if ((reply.length > 0) || reply_is_always_array) {
204 const GLint bytes = (reply_is_always_array)
205 ? (4 * reply.length) : (reply.size * size);
206 const GLint extra = 4 - (bytes & 3);
207
208 _XRead(dpy, dest, bytes);
209 if ( extra < 4 ) {
210 _XEatData(dpy, extra);
211 }
212 }
213 else {
214 (void) memcpy( dest, &(reply.pad3), size);
215 }
216 }
217
218 return reply.retval;
219 }
220
221 NOINLINE void
222 __glXReadPixelReply( Display *dpy, struct glx_context * gc, unsigned max_dim,
223 GLint width, GLint height, GLint depth, GLenum format, GLenum type,
224 void * dest, GLboolean dimensions_in_reply )
225 {
226 xGLXSingleReply reply;
227 GLint size;
228
229 (void) _XReply(dpy, (xReply *) & reply, 0, False);
230
231 if ( dimensions_in_reply ) {
232 width = reply.pad3;
233 height = reply.pad4;
234 depth = reply.pad5;
235
236 if ((height == 0) || (max_dim < 2)) { height = 1; }
237 if ((depth == 0) || (max_dim < 3)) { depth = 1; }
238 }
239
240 size = reply.length * 4;
241 if (size != 0) {
242 void * buf = malloc( size );
243
244 if ( buf == NULL ) {
245 _XEatData(dpy, size);
246 __glXSetError(gc, GL_OUT_OF_MEMORY);
247 }
248 else {
249 const GLint extra = 4 - (size & 3);
250
251 _XRead(dpy, buf, size);
252 if ( extra < 4 ) {
253 _XEatData(dpy, extra);
254 }
255
256 __glEmptyImage(gc, 3, width, height, depth, format, type,
257 buf, dest);
258 free(buf);
259 }
260 }
261 }
262
263 #define X_GLXSingle 0
264
265 NOINLINE FASTCALL GLubyte *
266 __glXSetupSingleRequest( struct glx_context * gc, GLint sop, GLint cmdlen )
267 {
268 xGLXSingleReq * req;
269 Display * const dpy = gc->currentDpy;
270
271 (void) __glXFlushRenderBuffer(gc, gc->pc);
272 LockDisplay(dpy);
273 GetReqExtra(GLXSingle, cmdlen, req);
274 req->reqType = gc->majorOpcode;
275 req->contextTag = gc->currentContextTag;
276 req->glxCode = sop;
277 return (GLubyte *)(req) + sz_xGLXSingleReq;
278 }
279
280 NOINLINE FASTCALL GLubyte *
281 __glXSetupVendorRequest( struct glx_context * gc, GLint code, GLint vop, GLint cmdlen )
282 {
283 xGLXVendorPrivateReq * req;
284 Display * const dpy = gc->currentDpy;
285
286 (void) __glXFlushRenderBuffer(gc, gc->pc);
287 LockDisplay(dpy);
288 GetReqExtra(GLXVendorPrivate, cmdlen, req);
289 req->reqType = gc->majorOpcode;
290 req->glxCode = code;
291 req->vendorCode = vop;
292 req->contextTag = gc->currentContextTag;
293 return (GLubyte *)(req) + sz_xGLXVendorPrivateReq;
294 }
295
296 const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 };
297
298 #define zero (__glXDefaultPixelStore+0)
299 #define one (__glXDefaultPixelStore+8)
300 #define default_pixel_store_1D (__glXDefaultPixelStore+4)
301 #define default_pixel_store_1D_size 20
302 #define default_pixel_store_2D (__glXDefaultPixelStore+4)
303 #define default_pixel_store_2D_size 20
304 #define default_pixel_store_3D (__glXDefaultPixelStore+0)
305 #define default_pixel_store_3D_size 36
306 #define default_pixel_store_4D (__glXDefaultPixelStore+0)
307 #define default_pixel_store_4D_size 36
308 """
309
310 for size in self.generic_sizes:
311 self.print_generic_function(size)
312 return
313
314
315 def printBody(self, api):
316
317 self.pixel_stubs = {}
318 generated_stubs = []
319
320 for func in api.functionIterateGlx():
321 if func.client_handcode: continue
322
323 # If the function is a pixel function with a certain
324 # GLX protocol signature, create a fake stub function
325 # for it. For example, create a single stub function
326 # that is used to implement both glTexImage1D and
327 # glTexImage2D.
328
329 if func.glx_rop != 0:
330 do_it = 0
331 for image in func.get_images():
332 if image.img_pad_dimensions:
333 do_it = 1
334 break
335
336
337 if do_it:
338 [h, n] = hash_pixel_function(func)
339
340
341 self.pixel_stubs[ func.name ] = n
342 if h not in generated_stubs:
343 generated_stubs.append(h)
344
345 fake_func = glx_pixel_function_stub( func, n )
346 self.printFunction(fake_func, fake_func.name)
347
348
349 self.printFunction(func, func.name)
350 if func.glx_sop and func.glx_vendorpriv:
351 self.printFunction(func, func.glx_vendorpriv_names[0])
352
353 self.printGetProcAddress(api)
354 return
355
356 def printGetProcAddress(self, api):
357 procs = {}
358 for func in api.functionIterateGlx():
359 for n in func.entry_points:
360 if func.has_different_protocol(n):
361 procs[n] = func.static_glx_name(n)
362
363 print """
364 #ifdef GLX_SHARED_GLAPI
365
366 static const struct proc_pair
367 {
368 const char *name;
369 _glapi_proc proc;
370 } proc_pairs[%d] = {""" % len(procs)
371 names = procs.keys()
372 names.sort()
373 for i in xrange(len(names)):
374 comma = ',' if i < len(names) - 1 else ''
375 print ' { "%s", (_glapi_proc) gl%s }%s' % (names[i], procs[names[i]], comma)
376 print """};
377
378 static int
379 __indirect_get_proc_compare(const void *key, const void *memb)
380 {
381 const struct proc_pair *pair = (const struct proc_pair *) memb;
382 return strcmp((const char *) key, pair->name);
383 }
384
385 _glapi_proc
386 __indirect_get_proc_address(const char *name)
387 {
388 const struct proc_pair *pair;
389
390 /* skip "gl" */
391 name += 2;
392
393 pair = (const struct proc_pair *) bsearch((const void *) name,
394 (const void *) proc_pairs, ARRAY_SIZE(proc_pairs), sizeof(proc_pairs[0]),
395 __indirect_get_proc_compare);
396
397 return (pair) ? pair->proc : NULL;
398 }
399
400 #endif /* GLX_SHARED_GLAPI */
401 """
402 return
403
404
405 def printFunction(self, func, name):
406 footer = '}\n'
407 if func.glx_rop == ~0:
408 print 'static %s' % (func.return_type)
409 print '%s( unsigned opcode, unsigned dim, %s )' % (func.name, func.get_parameter_string())
410 print '{'
411 else:
412 if func.has_different_protocol(name):
413 if func.return_type == "void":
414 ret_string = ''
415 else:
416 ret_string = "return "
417
418 func_name = func.static_glx_name(name)
419 print '#define %s %d' % (func.opcode_vendor_name(name), func.glx_vendorpriv)
420 print '%s gl%s(%s)' % (func.return_type, func_name, func.get_parameter_string())
421 print '{'
422 print ' struct glx_context * const gc = __glXGetCurrentContext();'
423 print ''
424 print '#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)'
425 print ' if (gc->isDirect) {'
426 print ' const _glapi_proc *const disp_table = (_glapi_proc *)GET_DISPATCH();'
427 print ' PFNGL%sPROC p =' % (name.upper())
428 print ' (PFNGL%sPROC) disp_table[%d];' % (name.upper(), func.offset)
429 print ' %sp(%s);' % (ret_string, func.get_called_parameter_string())
430 print ' } else'
431 print '#endif'
432 print ' {'
433
434 footer = '}\n}\n'
435 else:
436 print '#define %s %d' % (func.opcode_name(), func.opcode_value())
437
438 print '%s __indirect_gl%s(%s)' % (func.return_type, name, func.get_parameter_string())
439 print '{'
440
441
442 if func.glx_rop != 0 or func.vectorequiv != None:
443 if len(func.images):
444 self.printPixelFunction(func)
445 else:
446 self.printRenderFunction(func)
447 elif func.glx_sop != 0 or func.glx_vendorpriv != 0:
448 self.printSingleFunction(func, name)
449 pass
450 else:
451 print "/* Missing GLX protocol for %s. */" % (name)
452
453 print footer
454 return
455
456
457 def print_generic_function(self, n):
458 size = (n + 3) & ~3
459 print """static FASTCALL NOINLINE void
460 generic_%u_byte( GLint rop, const void * ptr )
461 {
462 struct glx_context * const gc = __glXGetCurrentContext();
463 const GLuint cmdlen = %u;
464
465 emit_header(gc->pc, rop, cmdlen);
466 (void) memcpy((void *)(gc->pc + 4), ptr, %u);
467 gc->pc += cmdlen;
468 if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }
469 }
470 """ % (n, size + 4, size)
471 return
472
473
474 def common_emit_one_arg(self, p, pc, adjust, extra_offset):
475 if p.is_array():
476 src_ptr = p.name
477 else:
478 src_ptr = "&" + p.name
479
480 if p.is_padding:
481 print '(void) memset((void *)(%s + %u), 0, %s);' \
482 % (pc, p.offset + adjust, p.size_string() )
483 elif not extra_offset:
484 print '(void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
485 % (pc, p.offset + adjust, src_ptr, p.size_string() )
486 else:
487 print '(void) memcpy((void *)(%s + %u + %s), (void *)(%s), %s);' \
488 % (pc, p.offset + adjust, extra_offset, src_ptr, p.size_string() )
489
490 def common_emit_args(self, f, pc, adjust, skip_vla):
491 extra_offset = None
492
493 for p in f.parameterIterateGlxSend( not skip_vla ):
494 if p.name != f.img_reset:
495 self.common_emit_one_arg(p, pc, adjust, extra_offset)
496
497 if p.is_variable_length():
498 temp = p.size_string()
499 if extra_offset:
500 extra_offset += " + %s" % (temp)
501 else:
502 extra_offset = temp
503
504 return
505
506
507 def pixel_emit_args(self, f, pc, large):
508 """Emit the arguments for a pixel function. This differs from
509 common_emit_args in that pixel functions may require padding
510 be inserted (i.e., for the missing width field for
511 TexImage1D), and they may also require a 'NULL image' flag
512 be inserted before the image data."""
513
514 if large:
515 adjust = 8
516 else:
517 adjust = 4
518
519 for param in f.parameterIterateGlxSend():
520 if not param.is_image():
521 self.common_emit_one_arg(param, pc, adjust, None)
522
523 if f.pad_after(param):
524 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc, (param.offset + param.size()) + adjust)
525
526 else:
527 [dim, width, height, depth, extent] = param.get_dimensions()
528 if f.glx_rop == ~0:
529 dim_str = "dim"
530 else:
531 dim_str = str(dim)
532
533 if param.is_padding:
534 print '(void) memset((void *)(%s + %u), 0, %s);' \
535 % (pc, (param.offset - 4) + adjust, param.size_string() )
536
537 if param.img_null_flag:
538 if large:
539 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc, (param.offset - 4) + adjust)
540 else:
541 print '(void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (pc, (param.offset - 4) + adjust, param.name)
542
543
544 pixHeaderPtr = "%s + %u" % (pc, adjust)
545 pcPtr = "%s + %u" % (pc, param.offset + adjust)
546
547 if not large:
548 if param.img_send_null:
549 condition = '(compsize > 0) && (%s != NULL)' % (param.name)
550 else:
551 condition = 'compsize > 0'
552
553 print 'if (%s) {' % (condition)
554 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)
555 print '} else {'
556 print ' (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (pixHeaderPtr, dim, dim)
557 print '}'
558 else:
559 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)
560
561 return
562
563
564 def large_emit_begin(self, f, op_name = None):
565 if not op_name:
566 op_name = f.opcode_real_name()
567
568 print 'const GLint op = %s;' % (op_name)
569 print 'const GLuint cmdlenLarge = cmdlen + 4;'
570 print 'GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);'
571 print '(void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);'
572 print '(void) memcpy((void *)(pc + 4), (void *)(&op), 4);'
573 return
574
575
576 def common_func_print_just_start(self, f, name):
577 print ' struct glx_context * const gc = __glXGetCurrentContext();'
578
579 # The only reason that single and vendor private commands need
580 # a variable called 'dpy' is becuase they use the SyncHandle
581 # macro. For whatever brain-dead reason, that macro is hard-
582 # coded to use a variable called 'dpy' instead of taking a
583 # parameter.
584
585 # FIXME Simplify the logic related to skip_condition and
586 # FIXME condition_list in this function. Basically, remove
587 # FIXME skip_condition, and just append the "dpy != NULL" type
588 # FIXME condition to condition_list from the start. The only
589 # FIXME reason it's done in this confusing way now is to
590 # FIXME minimize the diffs in the generated code.
591
592 if not f.glx_rop:
593 for p in f.parameterIterateOutputs():
594 if p.is_image() and (p.img_format != "GL_COLOR_INDEX" or p.img_type != "GL_BITMAP"):
595 print ' const __GLXattribute * const state = gc->client_state_private;'
596 break
597
598 print ' Display * const dpy = gc->currentDpy;'
599 skip_condition = "dpy != NULL"
600 elif f.can_be_large:
601 skip_condition = "gc->currentDpy != NULL"
602 else:
603 skip_condition = None
604
605
606 if f.return_type != 'void':
607 print ' %s retval = (%s) 0;' % (f.return_type, f.return_type)
608
609
610 if name != None and name not in f.glx_vendorpriv_names:
611 print '#ifndef USE_XCB'
612 self.emit_packet_size_calculation(f, 0)
613 if name != None and name not in f.glx_vendorpriv_names:
614 print '#endif'
615
616 condition_list = []
617 for p in f.parameterIterateCounters():
618 condition_list.append( "%s >= 0" % (p.name) )
619 # 'counter' parameters cannot be negative
620 print " if (%s < 0) {" % p.name
621 print " __glXSetError(gc, GL_INVALID_VALUE);"
622 if f.return_type != 'void':
623 print " return 0;"
624 else:
625 print " return;"
626 print " }"
627
628 if skip_condition:
629 condition_list.append( skip_condition )
630
631 if len( condition_list ) > 0:
632 if len( condition_list ) > 1:
633 skip_condition = "(%s)" % (string.join( condition_list, ") && (" ))
634 else:
635 skip_condition = "%s" % (condition_list.pop(0))
636
637 print ' if (__builtin_expect(%s, 1)) {' % (skip_condition)
638 return 1
639 else:
640 return 0
641
642
643 def printSingleFunction(self, f, name):
644 self.common_func_print_just_start(f, name)
645
646 if self.debug:
647 print ' printf( "Enter %%s...\\n", "gl%s" );' % (f.name)
648
649 if name not in f.glx_vendorpriv_names:
650
651 # XCB specific:
652 print '#ifdef USE_XCB'
653 if self.debug:
654 print ' printf("\\tUsing XCB.\\n");'
655 print ' xcb_connection_t *c = XGetXCBConnection(dpy);'
656 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
657 xcb_name = 'xcb_glx%s' % convertStringForXCB(name)
658
659 iparams=[]
660 extra_iparams = []
661 output = None
662 for p in f.parameterIterator():
663 if p.is_output:
664 output = p
665
666 if p.is_image():
667 if p.img_format != "GL_COLOR_INDEX" or p.img_type != "GL_BITMAP":
668 extra_iparams.append("state->storePack.swapEndian")
669 else:
670 extra_iparams.append("0")
671
672 # Hardcode this in. lsb_first param (apparently always GL_FALSE)
673 # also present in GetPolygonStipple, but taken care of above.
674 if xcb_name == "xcb_glx_read_pixels":
675 extra_iparams.append("0")
676 else:
677 iparams.append(p.name)
678
679
680 xcb_request = '%s(%s)' % (xcb_name, ", ".join(["c", "gc->currentContextTag"] + iparams + extra_iparams))
681
682 if f.needs_reply():
683 print ' %s_reply_t *reply = %s_reply(c, %s, NULL);' % (xcb_name, xcb_name, xcb_request)
684 if output:
685 if output.is_image():
686 [dim, w, h, d, junk] = output.get_dimensions()
687 if f.dimensions_in_reply:
688 w = "reply->width"
689 h = "reply->height"
690 d = "reply->depth"
691 if dim < 2:
692 h = "1"
693 else:
694 print ' if (%s == 0) { %s = 1; }' % (h, h)
695 if dim < 3:
696 d = "1"
697 else:
698 print ' if (%s == 0) { %s = 1; }' % (d, d)
699
700 print ' __glEmptyImage(gc, 3, %s, %s, %s, %s, %s, %s_data(reply), %s);' % (w, h, d, output.img_format, output.img_type, xcb_name, output.name)
701 else:
702 if f.reply_always_array:
703 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output.name, xcb_name, xcb_name, output.get_base_type_string())
704 else:
705 print ' if (%s_data_length(reply) == 0)' % (xcb_name)
706 print ' (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output.name)
707 print ' else'
708 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output.name, xcb_name, xcb_name, output.get_base_type_string())
709
710 if f.return_type != 'void':
711 print ' retval = reply->ret_val;'
712 print ' free(reply);'
713 else:
714 print ' ' + xcb_request + ';'
715 print '#else'
716 # End of XCB specific.
717
718
719 if f.parameters != []:
720 pc_decl = "GLubyte const * pc ="
721 else:
722 pc_decl = "(void)"
723
724 if name in f.glx_vendorpriv_names:
725 print ' %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl, f.opcode_real_name(), f.opcode_vendor_name(name))
726 else:
727 print ' %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl, f.opcode_name())
728
729 self.common_emit_args(f, "pc", 0, 0)
730
731 images = f.get_images()
732
733 for img in images:
734 if img.is_output:
735 o = f.command_fixed_length() - 4
736 print ' *(int32_t *)(pc + %u) = 0;' % (o)
737 if img.img_format != "GL_COLOR_INDEX" or img.img_type != "GL_BITMAP":
738 print ' * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o)
739
740 if f.img_reset:
741 print ' * (int8_t *)(pc + %u) = %s;' % (o + 1, f.img_reset)
742
743
744 return_name = ''
745 if f.needs_reply():
746 if f.return_type != 'void':
747 return_name = " retval"
748 return_str = " retval = (%s)" % (f.return_type)
749 else:
750 return_str = " (void)"
751
752 got_reply = 0
753
754 for p in f.parameterIterateOutputs():
755 if p.is_image():
756 [dim, w, h, d, junk] = p.get_dimensions()
757 if f.dimensions_in_reply:
758 print " __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim, p.img_format, p.img_type, p.name)
759 else:
760 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)
761
762 got_reply = 1
763 else:
764 if f.reply_always_array:
765 aa = "GL_TRUE"
766 else:
767 aa = "GL_FALSE"
768
769 # gl_parameter.size() returns the size
770 # of the entire data item. If the
771 # item is a fixed-size array, this is
772 # the size of the whole array. This
773 # is not what __glXReadReply wants. It
774 # wants the size of a single data
775 # element in the reply packet.
776 # Dividing by the array size (1 for
777 # non-arrays) gives us this.
778
779 s = p.size() / p.get_element_count()
780 print " %s __glXReadReply(dpy, %s, %s, %s);" % (return_str, s, p.name, aa)
781 got_reply = 1
782
783
784 # If a reply wasn't read to fill an output parameter,
785 # read a NULL reply to get the return value.
786
787 if not got_reply:
788 print " %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str)
789
790
791 elif self.debug:
792 # Only emit the extra glFinish call for functions
793 # that don't already require a reply from the server.
794 print ' __indirect_glFinish();'
795
796 if self.debug:
797 print ' printf( "Exit %%s.\\n", "gl%s" );' % (name)
798
799
800 print ' UnlockDisplay(dpy); SyncHandle();'
801
802 if name not in f.glx_vendorpriv_names:
803 print '#endif /* USE_XCB */'
804
805 print ' }'
806 print ' return%s;' % (return_name)
807 return
808
809
810 def printPixelFunction(self, f):
811 if self.pixel_stubs.has_key( f.name ):
812 # Normally gl_function::get_parameter_string could be
813 # used. However, this call needs to have the missing
814 # dimensions (e.g., a fake height value for
815 # glTexImage1D) added in.
816
817 p_string = ""
818 for param in f.parameterIterateGlxSend():
819 if param.is_padding:
820 continue
821
822 p_string += ", " + param.name
823
824 if param.is_image():
825 [dim, junk, junk, junk, junk] = param.get_dimensions()
826
827 if f.pad_after(param):
828 p_string += ", 1"
829
830 print ' %s(%s, %u%s );' % (self.pixel_stubs[f.name] , f.opcode_name(), dim, p_string)
831 return
832
833
834 if self.common_func_print_just_start(f, None):
835 trailer = " }"
836 else:
837 trailer = None
838
839
840 if f.can_be_large:
841 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
842 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
843 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
844 print ' }'
845
846 if f.glx_rop == ~0:
847 opcode = "opcode"
848 else:
849 opcode = f.opcode_real_name()
850
851 print 'emit_header(gc->pc, %s, cmdlen);' % (opcode)
852
853 self.pixel_emit_args( f, "gc->pc", 0 )
854 print 'gc->pc += cmdlen;'
855 print 'if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
856
857 if f.can_be_large:
858 print '}'
859 print 'else {'
860
861 self.large_emit_begin(f, opcode)
862 self.pixel_emit_args(f, "pc", 1)
863
864 print '}'
865
866 if trailer: print trailer
867 return
868
869
870 def printRenderFunction(self, f):
871 # There is a class of GL functions that take a single pointer
872 # as a parameter. This pointer points to a fixed-size chunk
873 # of data, and the protocol for this functions is very
874 # regular. Since they are so regular and there are so many
875 # of them, special case them with generic functions. On
876 # x86, this saves about 26KB in the libGL.so binary.
877
878 if f.variable_length_parameter() == None and len(f.parameters) == 1:
879 p = f.parameters[0]
880 if p.is_pointer():
881 cmdlen = f.command_fixed_length()
882 if cmdlen in self.generic_sizes:
883 print ' generic_%u_byte( %s, %s );' % (cmdlen, f.opcode_real_name(), p.name)
884 return
885
886 if self.common_func_print_just_start(f, None):
887 trailer = " }"
888 else:
889 trailer = None
890
891 if self.debug:
892 print 'printf( "Enter %%s...\\n", "gl%s" );' % (f.name)
893
894 if f.can_be_large:
895 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
896 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
897 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
898 print ' }'
899
900 print 'emit_header(gc->pc, %s, cmdlen);' % (f.opcode_real_name())
901
902 self.common_emit_args(f, "gc->pc", 4, 0)
903 print 'gc->pc += cmdlen;'
904 print 'if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
905
906 if f.can_be_large:
907 print '}'
908 print 'else {'
909
910 self.large_emit_begin(f)
911 self.common_emit_args(f, "pc", 8, 1)
912
913 p = f.variable_length_parameter()
914 print ' __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (p.offset + 8, p.name, p.size_string())
915 print '}'
916
917 if self.debug:
918 print '__indirect_glFinish();'
919 print 'printf( "Exit %%s.\\n", "gl%s" );' % (f.name)
920
921 if trailer: print trailer
922 return
923
924
925 class PrintGlxProtoInit_c(gl_XML.gl_print_base):
926 def __init__(self):
927 gl_XML.gl_print_base.__init__(self)
928
929 self.name = "glX_proto_send.py (from Mesa)"
930 self.license = license.bsd_license_template % ( \
931 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
932 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
933 return
934
935
936 def printRealHeader(self):
937 print """/**
938 * \\file indirect_init.c
939 * Initialize indirect rendering dispatch table.
940 *
941 * \\author Kevin E. Martin <kevin@precisioninsight.com>
942 * \\author Brian Paul <brian@precisioninsight.com>
943 * \\author Ian Romanick <idr@us.ibm.com>
944 */
945
946 #include "indirect_init.h"
947 #include "indirect.h"
948 #include "glapi.h"
949 #include <assert.h>
950
951
952 /**
953 * No-op function used to initialize functions that have no GLX protocol
954 * support.
955 */
956 static int NoOp(void)
957 {
958 return 0;
959 }
960
961 /**
962 * Create and initialize a new GL dispatch table. The table is initialized
963 * with GLX indirect rendering protocol functions.
964 */
965 struct _glapi_table * __glXNewIndirectAPI( void )
966 {
967 _glapi_proc *table;
968 unsigned entries;
969 unsigned i;
970 int o;
971
972 entries = _glapi_get_dispatch_table_size();
973 table = malloc(entries * sizeof(_glapi_proc));
974
975 /* first, set all entries to point to no-op functions */
976 for (i = 0; i < entries; i++) {
977 table[i] = (_glapi_proc) NoOp;
978 }
979
980 /* now, initialize the entries we understand */"""
981
982 def printRealFooter(self):
983 print """
984 return (struct _glapi_table *) table;
985 }
986 """
987 return
988
989
990 def printBody(self, api):
991 for [name, number] in api.categoryIterate():
992 if number != None:
993 preamble = '\n /* %3u. %s */\n' % (int(number), name)
994 else:
995 preamble = '\n /* %s */\n' % (name)
996
997 for func in api.functionIterateByCategory(name):
998 if func.client_supported_for_indirect():
999 if preamble:
1000 print preamble
1001 preamble = None
1002
1003 if func.is_abi():
1004 print ' table[{offset}] = (_glapi_proc) __indirect_gl{name};'.format(name = func.name, offset = func.offset)
1005 else:
1006 print ' o = _glapi_get_proc_offset("gl{0}");'.format(func.name)
1007 print ' assert(o > 0);'
1008 print ' table[o] = (_glapi_proc) __indirect_gl{0};'.format(func.name)
1009
1010 return
1011
1012
1013 class PrintGlxProtoInit_h(gl_XML.gl_print_base):
1014 def __init__(self):
1015 gl_XML.gl_print_base.__init__(self)
1016
1017 self.name = "glX_proto_send.py (from Mesa)"
1018 self.license = license.bsd_license_template % ( \
1019 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
1020 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
1021 self.header_tag = "_INDIRECT_H_"
1022
1023 self.last_category = ""
1024 return
1025
1026
1027 def printRealHeader(self):
1028 print """/**
1029 * \\file
1030 * Prototypes for indirect rendering functions.
1031 *
1032 * \\author Kevin E. Martin <kevin@precisioninsight.com>
1033 * \\author Ian Romanick <idr@us.ibm.com>
1034 */
1035 """
1036 self.printFastcall()
1037 self.printNoinline()
1038
1039 print """
1040 #include <X11/Xfuncproto.h>
1041 #include "glxclient.h"
1042
1043 extern _X_HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
1044 void * dest, GLboolean reply_is_always_array );
1045
1046 extern _X_HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
1047 struct glx_context * gc, unsigned max_dim, GLint width, GLint height,
1048 GLint depth, GLenum format, GLenum type, void * dest,
1049 GLboolean dimensions_in_reply );
1050
1051 extern _X_HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
1052 struct glx_context * gc, GLint sop, GLint cmdlen );
1053
1054 extern _X_HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
1055 struct glx_context * gc, GLint code, GLint vop, GLint cmdlen );
1056 """
1057
1058
1059 def printBody(self, api):
1060 for func in api.functionIterateGlx():
1061 params = func.get_parameter_string()
1062
1063 print 'extern _X_HIDDEN %s __indirect_gl%s(%s);' % (func.return_type, func.name, params)
1064
1065 for n in func.entry_points:
1066 if func.has_different_protocol(n):
1067 asdf = func.static_glx_name(n)
1068 if asdf not in func.static_entry_points:
1069 print 'extern _X_HIDDEN %s gl%s(%s);' % (func.return_type, asdf, params)
1070 # give it a easy-to-remember name
1071 if func.client_handcode:
1072 print '#define gl_dispatch_stub_%s gl%s' % (n, asdf)
1073 else:
1074 print 'GLAPI %s GLAPIENTRY gl%s(%s);' % (func.return_type, asdf, params)
1075
1076 break
1077
1078 print ''
1079 print '#ifdef GLX_SHARED_GLAPI'
1080 print 'extern _X_HIDDEN void (*__indirect_get_proc_address(const char *name))(void);'
1081 print '#endif'
1082
1083
1084 def show_usage():
1085 print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys.argv[0]
1086 print " -m output_mode Output mode can be one of 'proto', 'init_c' or 'init_h'."
1087 print " -d Enable extra debug information in the generated code."
1088 sys.exit(1)
1089
1090
1091 if __name__ == '__main__':
1092 file_name = "gl_API.xml"
1093
1094 try:
1095 (args, trail) = getopt.getopt(sys.argv[1:], "f:m:d")
1096 except Exception,e:
1097 show_usage()
1098
1099 debug = 0
1100 mode = "proto"
1101 for (arg,val) in args:
1102 if arg == "-f":
1103 file_name = val
1104 elif arg == "-m":
1105 mode = val
1106 elif arg == "-d":
1107 debug = 1
1108
1109 if mode == "proto":
1110 printer = PrintGlxProtoStubs()
1111 elif mode == "init_c":
1112 printer = PrintGlxProtoInit_c()
1113 elif mode == "init_h":
1114 printer = PrintGlxProtoInit_h()
1115 else:
1116 show_usage()
1117
1118
1119 printer.debug = debug
1120 api = gl_XML.parse_GL_API( file_name, glX_XML.glx_item_factory() )
1121
1122 printer.Print( api )