include glapi.h to fix broken build
[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):
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():
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 self.emit_packet_size_calculation(f, 0)
549
550 condition_list = []
551 for p in f.parameterIterateCounters():
552 condition_list.append( "%s >= 0" % (p.name) )
553
554 if skip_condition:
555 condition_list.append( skip_condition )
556
557 if len( condition_list ) > 0:
558 if len( condition_list ) > 1:
559 skip_condition = "(%s)" % (string.join( condition_list, ") && (" ))
560 else:
561 skip_condition = "%s" % (condition_list.pop(0))
562
563 print ' if (__builtin_expect(%s, 1)) {' % (skip_condition)
564 return 1
565 else:
566 return 0
567
568
569 def printSingleFunction(self, f, name):
570 self.common_func_print_just_start(f)
571
572 if self.debug:
573 print ' printf( "Enter %%s...\\n", "gl%s" );' % (f.name)
574
575 if name not in f.glx_vendorpriv_names:
576
577 # XCB specific:
578 print '#ifdef USE_XCB'
579 if self.debug:
580 print ' printf("\\tUsing XCB.\\n");'
581 print ' xcb_connection_t *c = XGetXCBConnection(dpy);'
582 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
583 xcb_name = 'xcb_glx%s' % convertStringForXCB(name)
584
585 iparams=[]
586 extra_iparams = []
587 output = None
588 for p in f.parameterIterator():
589 if p.is_output:
590 output = p
591
592 if p.is_image():
593 if p.img_format != "GL_COLOR_INDEX" or p.img_type != "GL_BITMAP":
594 extra_iparams.append("state->storePack.swapEndian")
595 else:
596 extra_iparams.append("0")
597
598 # Hardcode this in. lsb_first param (apparently always GL_FALSE)
599 # also present in GetPolygonStipple, but taken care of above.
600 if xcb_name == "xcb_glx_read_pixels":
601 extra_iparams.append("0")
602 else:
603 iparams.append(p.name)
604
605
606 xcb_request = '%s(%s)' % (xcb_name, ", ".join(["c", "gc->currentContextTag"] + iparams + extra_iparams))
607
608 if f.needs_reply():
609 print ' %s_reply_t *reply = %s_reply(c, %s, NULL);' % (xcb_name, xcb_name, xcb_request)
610 if output and f.reply_always_array:
611 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output.name, xcb_name, xcb_name, output.get_base_type_string())
612
613 elif output and not f.reply_always_array:
614 if not output.is_image():
615 print ' if (%s_data_length(reply) == 0)' % (xcb_name)
616 print ' (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output.name)
617 print ' else'
618 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output.name, xcb_name, xcb_name, output.get_base_type_string())
619
620
621 if f.return_type != 'void':
622 print ' retval = reply->ret_val;'
623 print ' free(reply);'
624 else:
625 print ' ' + xcb_request + ';'
626 print '#else'
627 # End of XCB specific.
628
629
630 if f.parameters != []:
631 pc_decl = "GLubyte const * pc ="
632 else:
633 pc_decl = "(void)"
634
635 if name in f.glx_vendorpriv_names:
636 print ' %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl, f.opcode_real_name(), f.opcode_vendor_name(name))
637 else:
638 print ' %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl, f.opcode_name())
639
640 self.common_emit_args(f, "pc", 0, 0)
641
642 images = f.get_images()
643
644 for img in images:
645 if img.is_output:
646 o = f.command_fixed_length() - 4
647 print ' *(int32_t *)(pc + %u) = 0;' % (o)
648 if img.img_format != "GL_COLOR_INDEX" or img.img_type != "GL_BITMAP":
649 print ' * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o)
650
651 if f.img_reset:
652 print ' * (int8_t *)(pc + %u) = %s;' % (o + 1, f.img_reset)
653
654
655 return_name = ''
656 if f.needs_reply():
657 if f.return_type != 'void':
658 return_name = " retval"
659 return_str = " retval = (%s)" % (f.return_type)
660 else:
661 return_str = " (void)"
662
663 got_reply = 0
664
665 for p in f.parameterIterateOutputs():
666 if p.is_image():
667 [dim, w, h, d, junk] = p.get_dimensions()
668 if f.dimensions_in_reply:
669 print " __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim, p.img_format, p.img_type, p.name)
670 else:
671 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)
672
673 got_reply = 1
674 else:
675 if f.reply_always_array:
676 aa = "GL_TRUE"
677 else:
678 aa = "GL_FALSE"
679
680 # gl_parameter.size() returns the size
681 # of the entire data item. If the
682 # item is a fixed-size array, this is
683 # the size of the whole array. This
684 # is not what __glXReadReply wants. It
685 # wants the size of a single data
686 # element in the reply packet.
687 # Dividing by the array size (1 for
688 # non-arrays) gives us this.
689
690 s = p.size() / p.get_element_count()
691 print " %s __glXReadReply(dpy, %s, %s, %s);" % (return_str, s, p.name, aa)
692 got_reply = 1
693
694
695 # If a reply wasn't read to fill an output parameter,
696 # read a NULL reply to get the return value.
697
698 if not got_reply:
699 print " %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str)
700
701
702 elif self.debug:
703 # Only emit the extra glFinish call for functions
704 # that don't already require a reply from the server.
705 print ' __indirect_glFinish();'
706
707 if self.debug:
708 print ' printf( "Exit %%s.\\n", "gl%s" );' % (name)
709
710
711 print ' UnlockDisplay(dpy); SyncHandle();'
712
713 if name not in f.glx_vendorpriv_names:
714 print '#endif /* USE_XCB */'
715
716 print ' }'
717 print ' return%s;' % (return_name)
718 return
719
720
721 def printPixelFunction(self, f):
722 if self.pixel_stubs.has_key( f.name ):
723 # Normally gl_function::get_parameter_string could be
724 # used. However, this call needs to have the missing
725 # dimensions (e.g., a fake height value for
726 # glTexImage1D) added in.
727
728 p_string = ""
729 for param in f.parameterIterateGlxSend():
730 p_string += ", " + param.name
731
732 if param.is_image():
733 [dim, junk, junk, junk, junk] = param.get_dimensions()
734
735 if f.pad_after(param):
736 p_string += ", 1"
737
738 print ' %s(%s, %u%s );' % (self.pixel_stubs[f.name] , f.opcode_name(), dim, p_string)
739 return
740
741
742 if self.common_func_print_just_start(f):
743 trailer = " }"
744 else:
745 trailer = None
746
747
748 if f.can_be_large:
749 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
750 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
751 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
752 print ' }'
753
754 if f.glx_rop == ~0:
755 opcode = "opcode"
756 else:
757 opcode = f.opcode_real_name()
758
759 print 'emit_header(gc->pc, %s, cmdlen);' % (opcode)
760
761 self.pixel_emit_args( f, "gc->pc", 0 )
762 print 'gc->pc += cmdlen;'
763 print 'if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
764
765 if f.can_be_large:
766 print '}'
767 print 'else {'
768
769 self.large_emit_begin(f, opcode)
770 self.pixel_emit_args(f, "pc", 1)
771
772 print '}'
773
774 if trailer: print trailer
775 return
776
777
778 def printRenderFunction(self, f):
779 # There is a class of GL functions that take a single pointer
780 # as a parameter. This pointer points to a fixed-size chunk
781 # of data, and the protocol for this functions is very
782 # regular. Since they are so regular and there are so many
783 # of them, special case them with generic functions. On
784 # x86, this saves about 26KB in the libGL.so binary.
785
786 if f.variable_length_parameter() == None and len(f.parameters) == 1:
787 p = f.parameters[0]
788 if p.is_pointer():
789 cmdlen = f.command_fixed_length()
790 if cmdlen in self.generic_sizes:
791 print ' generic_%u_byte( %s, %s );' % (cmdlen, f.opcode_real_name(), p.name)
792 return
793
794 if self.common_func_print_just_start(f):
795 trailer = " }"
796 else:
797 trailer = None
798
799 if self.debug:
800 print 'printf( "Enter %%s...\\n", "gl%s" );' % (f.name)
801
802 if f.can_be_large:
803 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
804 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
805 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
806 print ' }'
807
808 print 'emit_header(gc->pc, %s, cmdlen);' % (f.opcode_real_name())
809
810 self.common_emit_args(f, "gc->pc", 4, 0)
811 print 'gc->pc += cmdlen;'
812 print 'if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
813
814 if f.can_be_large:
815 print '}'
816 print 'else {'
817
818 self.large_emit_begin(f)
819 self.common_emit_args(f, "pc", 8, 1)
820
821 p = f.variable_length_parameter()
822 print ' __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (p.offset + 8, p.name, p.size_string())
823 print '}'
824
825 if self.debug:
826 print '__indirect_glFinish();'
827 print 'printf( "Exit %%s.\\n", "gl%s" );' % (f.name)
828
829 if trailer: print trailer
830 return
831
832
833 class PrintGlxProtoInit_c(gl_XML.gl_print_base):
834 def __init__(self):
835 gl_XML.gl_print_base.__init__(self)
836
837 self.name = "glX_proto_send.py (from Mesa)"
838 self.license = license.bsd_license_template % ( \
839 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
840 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
841 return
842
843
844 def printRealHeader(self):
845 print """/**
846 * \\file indirect_init.c
847 * Initialize indirect rendering dispatch table.
848 *
849 * \\author Kevin E. Martin <kevin@precisioninsight.com>
850 * \\author Brian Paul <brian@precisioninsight.com>
851 * \\author Ian Romanick <idr@us.ibm.com>
852 */
853
854 #include "indirect_init.h"
855 #include "indirect.h"
856 #include "glapi.h"
857
858
859 /**
860 * No-op function used to initialize functions that have no GLX protocol
861 * support.
862 */
863 static int NoOp(void)
864 {
865 return 0;
866 }
867
868 /**
869 * Create and initialize a new GL dispatch table. The table is initialized
870 * with GLX indirect rendering protocol functions.
871 */
872 __GLapi * __glXNewIndirectAPI( void )
873 {
874 __GLapi *glAPI;
875 GLuint entries;
876
877 entries = _glapi_get_dispatch_table_size();
878 glAPI = (__GLapi *) Xmalloc(entries * sizeof(void *));
879
880 /* first, set all entries to point to no-op functions */
881 {
882 int i;
883 void **dispatch = (void **) glAPI;
884 for (i = 0; i < entries; i++) {
885 dispatch[i] = (void *) NoOp;
886 }
887 }
888
889 /* now, initialize the entries we understand */"""
890
891 def printRealFooter(self):
892 print """
893 return glAPI;
894 }
895 """
896 return
897
898
899 def printBody(self, api):
900 for [name, number] in api.categoryIterate():
901 if number != None:
902 preamble = '\n /* %3u. %s */\n\n' % (int(number), name)
903 else:
904 preamble = '\n /* %s */\n\n' % (name)
905
906 for func in api.functionIterateByCategory(name):
907 if func.client_supported_for_indirect():
908 print '%s glAPI->%s = __indirect_gl%s;' % (preamble, func.name, func.name)
909 preamble = ''
910
911 return
912
913
914 class PrintGlxProtoInit_h(gl_XML.gl_print_base):
915 def __init__(self):
916 gl_XML.gl_print_base.__init__(self)
917
918 self.name = "glX_proto_send.py (from Mesa)"
919 self.license = license.bsd_license_template % ( \
920 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
921 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
922 self.header_tag = "_INDIRECT_H_"
923
924 self.last_category = ""
925 return
926
927
928 def printRealHeader(self):
929 print """/**
930 * \\file
931 * Prototypes for indirect rendering functions.
932 *
933 * \\author Kevin E. Martin <kevin@precisioninsight.com>
934 * \\author Ian Romanick <idr@us.ibm.com>
935 */
936 """
937 self.printVisibility( "HIDDEN", "hidden" )
938 self.printFastcall()
939 self.printNoinline()
940
941 print """
942 #include "glxclient.h"
943
944 extern HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
945 void * dest, GLboolean reply_is_always_array );
946
947 extern HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
948 __GLXcontext * gc, unsigned max_dim, GLint width, GLint height,
949 GLint depth, GLenum format, GLenum type, void * dest,
950 GLboolean dimensions_in_reply );
951
952 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
953 __GLXcontext * gc, GLint sop, GLint cmdlen );
954
955 extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
956 __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen );
957 """
958
959
960 def printBody(self, api):
961 for func in api.functionIterateGlx():
962 params = func.get_parameter_string()
963
964 print 'extern HIDDEN %s __indirect_gl%s(%s);' % (func.return_type, func.name, params)
965
966 for n in func.entry_points:
967 if func.has_different_protocol(n):
968 asdf = func.static_glx_name(n)
969 if asdf not in func.static_entry_points:
970 print 'extern HIDDEN %s gl%s(%s);' % (func.return_type, asdf, params)
971 else:
972 print 'GLAPI %s GLAPIENTRY gl%s(%s);' % (func.return_type, asdf, params)
973
974 break
975
976
977
978 def show_usage():
979 print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys.argv[0]
980 print " -m output_mode Output mode can be one of 'proto', 'init_c' or 'init_h'."
981 print " -d Enable extra debug information in the generated code."
982 sys.exit(1)
983
984
985 if __name__ == '__main__':
986 file_name = "gl_API.xml"
987
988 try:
989 (args, trail) = getopt.getopt(sys.argv[1:], "f:m:d")
990 except Exception,e:
991 show_usage()
992
993 debug = 0
994 mode = "proto"
995 for (arg,val) in args:
996 if arg == "-f":
997 file_name = val
998 elif arg == "-m":
999 mode = val
1000 elif arg == "-d":
1001 debug = 1
1002
1003 if mode == "proto":
1004 printer = PrintGlxProtoStubs()
1005 elif mode == "init_c":
1006 printer = PrintGlxProtoInit_c()
1007 elif mode == "init_h":
1008 printer = PrintGlxProtoInit_h()
1009 else:
1010 show_usage()
1011
1012
1013 printer.debug = debug
1014 api = gl_XML.parse_GL_API( file_name, glX_XML.glx_item_factory() )
1015
1016 printer.Print( api )