3 # (C) Copyright IBM Corporation 2004, 2005
5 # Copyright (c) 2015 Intel Corporation
7 # Permission is hereby granted, free of charge, to any person obtaining a
8 # copy of this software and associated documentation files (the "Software"),
9 # to deal in the Software without restriction, including without limitation
10 # on the rights to use, copy, modify, merge, publish, distribute, sub
11 # license, and/or sell copies of the Software, and to permit persons to whom
12 # the Software is furnished to do so, subject to the following conditions:
14 # The above copyright notice and this permission notice (including the next
15 # paragraph) shall be included in all copies or substantial portions of the
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 # IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
27 # Ian Romanick <idr@us.ibm.com>
28 # Jeremy Kolb <jkolb@brandeis.edu>
32 import gl_XML
, glX_XML
, glX_proto_common
, license
35 def convertStringForXCB(str):
40 if str[i
:i
+3] in special
:
41 tmp
= '%s_%s' % (tmp
, string
.lower(str[i
:i
+3]))
43 elif str[i
].isupper():
44 tmp
= '%s_%s' % (tmp
, string
.lower(str[i
]))
46 tmp
= '%s%s' % (tmp
, str[i
])
50 def hash_pixel_function(func
):
51 """Generate a 'unique' key for a pixel function. The key is based on
52 the parameters written in the command packet. This includes any
53 padding that might be added for the original function and the 'NULL
60 for param
in func
.parameterIterateGlxSend():
62 [dim
, junk
, junk
, junk
, junk
] = param
.get_dimensions()
65 hash_pre
= "%uD%uD_" % (d
- 1, d
)
67 if param
.img_null_flag
:
70 h
+= "%u" % (param
.size())
72 if func
.pad_after(param
):
76 n
= func
.name
.replace("%uD" % (dim
), "")
77 n
= "__glx_%s_%uD%uD" % (n
, d
- 1, d
)
79 h
= hash_pre
+ h
+ hash_suf
83 class glx_pixel_function_stub(glX_XML
.glx_function
):
84 """Dummy class used to generate pixel "utility" functions that are
85 shared by multiple dimension image functions. For example, these
86 objects are used to generate shared functions used to send GLX
87 protocol for TexImage1D and TexImage2D, TexSubImage1D and
88 TexSubImage2D, etc."""
90 def __init__(self
, func
, name
):
91 # The parameters to the utility function are the same as the
92 # parameters to the real function except for the added "pad"
98 self
.parameters_by_name
= {}
99 for _p
in func
.parameterIterator():
101 self
.parameters
.append(p
)
102 self
.parameters_by_name
[ p
.name
] = p
106 self
.images
.append(p
)
109 if p
.img_yoff
== None:
110 p
.img_yoff
= "yoffset"
116 if p
.img_woff
== None:
117 p
.img_woff
= "woffset"
120 pad_name
= func
.pad_after(p
)
124 self
.parameters
.append(pad
)
125 self
.parameters_by_name
[ pad
.name
] = pad
128 self
.return_type
= func
.return_type
132 self
.glx_vendorpriv
= 0
134 self
.glx_doubles_in_order
= func
.glx_doubles_in_order
136 self
.vectorequiv
= None
138 self
.can_be_large
= func
.can_be_large
139 self
.reply_always_array
= func
.reply_always_array
140 self
.dimensions_in_reply
= func
.dimensions_in_reply
141 self
.img_reset
= None
143 self
.server_handcode
= 0
144 self
.client_handcode
= 0
147 self
.count_parameter_list
= func
.count_parameter_list
148 self
.counter_list
= func
.counter_list
149 self
.offsets_calculated
= 0
153 class PrintGlxProtoStubs(glX_proto_common
.glx_print_proto
):
155 glX_proto_common
.glx_print_proto
.__init
__(self
)
156 self
.name
= "glX_proto_send.py (from Mesa)"
157 self
.license
= license
.bsd_license_template
% ( "(C) Copyright IBM Corporation 2004, 2005", "IBM")
160 self
.last_category
= ""
161 self
.generic_sizes
= [3, 4, 6, 8, 12, 16, 24, 32]
162 self
.pixel_stubs
= {}
166 def printRealHeader(self
):
168 print '#include <GL/gl.h>'
169 print '#include "indirect.h"'
170 print '#include "glxclient.h"'
171 print '#include "indirect_size.h"'
172 print '#include "glapi.h"'
173 print '#include <GL/glxproto.h>'
174 print '#include <X11/Xlib-xcb.h>'
175 print '#include <xcb/xcb.h>'
176 print '#include <xcb/glx.h>'
177 print '#include <limits.h>'
184 print 'static _X_INLINE int safe_add(int a, int b)'
186 print ' if (a < 0 || b < 0) return -1;'
187 print ' if (INT_MAX - a < b) return -1;'
188 print ' return a + b;'
190 print 'static _X_INLINE int safe_mul(int a, int b)'
192 print ' if (a < 0 || b < 0) return -1;'
193 print ' if (a == 0 || b == 0) return 0;'
194 print ' if (a > INT_MAX / b) return -1;'
195 print ' return a * b;'
197 print 'static _X_INLINE int safe_pad(int a)'
200 print ' if (a < 0) return -1;'
201 print ' if ((ret = safe_add(a, 3)) < 0) return -1;'
202 print ' return ret & (GLuint)~3;'
206 print '#ifndef __GNUC__'
207 print '# define __builtin_expect(x, y) x'
210 print '/* If the size and opcode values are known at compile-time, this will, on'
211 print ' * x86 at least, emit them with a single instruction.'
213 print '#define emit_header(dest, op, size) \\'
214 print ' do { union { short s[2]; int i; } temp; \\'
215 print ' temp.s[0] = (size); temp.s[1] = (op); \\'
216 print ' *((int *)(dest)) = temp.i; } while(0)'
218 print """NOINLINE CARD32
219 __glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array )
221 xGLXSingleReply reply;
223 (void) _XReply(dpy, (xReply *) & reply, 0, False);
225 if ((reply.length > 0) || reply_is_always_array) {
226 const GLint bytes = (reply_is_always_array)
227 ? (4 * reply.length) : (reply.size * size);
228 const GLint extra = 4 - (bytes & 3);
230 _XRead(dpy, dest, bytes);
232 _XEatData(dpy, extra);
236 (void) memcpy( dest, &(reply.pad3), size);
244 __glXReadPixelReply( Display *dpy, struct glx_context * gc, unsigned max_dim,
245 GLint width, GLint height, GLint depth, GLenum format, GLenum type,
246 void * dest, GLboolean dimensions_in_reply )
248 xGLXSingleReply reply;
251 (void) _XReply(dpy, (xReply *) & reply, 0, False);
253 if ( dimensions_in_reply ) {
258 if ((height == 0) || (max_dim < 2)) { height = 1; }
259 if ((depth == 0) || (max_dim < 3)) { depth = 1; }
262 size = reply.length * 4;
264 void * buf = malloc( size );
267 _XEatData(dpy, size);
268 __glXSetError(gc, GL_OUT_OF_MEMORY);
271 const GLint extra = 4 - (size & 3);
273 _XRead(dpy, buf, size);
275 _XEatData(dpy, extra);
278 __glEmptyImage(gc, 3, width, height, depth, format, type,
285 #define X_GLXSingle 0
287 NOINLINE FASTCALL GLubyte *
288 __glXSetupSingleRequest( struct glx_context * gc, GLint sop, GLint cmdlen )
291 Display * const dpy = gc->currentDpy;
293 (void) __glXFlushRenderBuffer(gc, gc->pc);
295 GetReqExtra(GLXSingle, cmdlen, req);
296 req->reqType = gc->majorOpcode;
297 req->contextTag = gc->currentContextTag;
299 return (GLubyte *)(req) + sz_xGLXSingleReq;
302 NOINLINE FASTCALL GLubyte *
303 __glXSetupVendorRequest( struct glx_context * gc, GLint code, GLint vop, GLint cmdlen )
305 xGLXVendorPrivateReq * req;
306 Display * const dpy = gc->currentDpy;
308 (void) __glXFlushRenderBuffer(gc, gc->pc);
310 GetReqExtra(GLXVendorPrivate, cmdlen, req);
311 req->reqType = gc->majorOpcode;
313 req->vendorCode = vop;
314 req->contextTag = gc->currentContextTag;
315 return (GLubyte *)(req) + sz_xGLXVendorPrivateReq;
318 const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 };
320 #define zero (__glXDefaultPixelStore+0)
321 #define one (__glXDefaultPixelStore+8)
322 #define default_pixel_store_1D (__glXDefaultPixelStore+4)
323 #define default_pixel_store_1D_size 20
324 #define default_pixel_store_2D (__glXDefaultPixelStore+4)
325 #define default_pixel_store_2D_size 20
326 #define default_pixel_store_3D (__glXDefaultPixelStore+0)
327 #define default_pixel_store_3D_size 36
328 #define default_pixel_store_4D (__glXDefaultPixelStore+0)
329 #define default_pixel_store_4D_size 36
332 for size
in self
.generic_sizes
:
333 self
.print_generic_function(size
)
337 def printBody(self
, api
):
339 self
.pixel_stubs
= {}
342 for func
in api
.functionIterateGlx():
343 if func
.client_handcode
: continue
345 # If the function is a pixel function with a certain
346 # GLX protocol signature, create a fake stub function
347 # for it. For example, create a single stub function
348 # that is used to implement both glTexImage1D and
351 if func
.glx_rop
!= 0:
353 for image
in func
.get_images():
354 if image
.img_pad_dimensions
:
360 [h
, n
] = hash_pixel_function(func
)
363 self
.pixel_stubs
[ func
.name
] = n
364 if h
not in generated_stubs
:
365 generated_stubs
.append(h
)
367 fake_func
= glx_pixel_function_stub( func
, n
)
368 self
.printFunction(fake_func
, fake_func
.name
)
371 self
.printFunction(func
, func
.name
)
372 if func
.glx_sop
and func
.glx_vendorpriv
:
373 self
.printFunction(func
, func
.glx_vendorpriv_names
[0])
375 self
.printGetProcAddress(api
)
378 def printGetProcAddress(self
, api
):
380 for func
in api
.functionIterateGlx():
381 for n
in func
.entry_points
:
382 if func
.has_different_protocol(n
):
383 procs
[n
] = func
.static_glx_name(n
)
386 #ifdef GLX_SHARED_GLAPI
388 static const struct proc_pair
392 } proc_pairs[%d] = {""" % len(procs
)
395 for i
in xrange(len(names
)):
396 comma
= ',' if i
< len(names
) - 1 else ''
397 print ' { "%s", (_glapi_proc) gl%s }%s' % (names
[i
], procs
[names
[i
]], comma
)
401 __indirect_get_proc_compare(const void *key, const void *memb)
403 const struct proc_pair *pair = (const struct proc_pair *) memb;
404 return strcmp((const char *) key, pair->name);
408 __indirect_get_proc_address(const char *name)
410 const struct proc_pair *pair;
415 pair = (const struct proc_pair *) bsearch((const void *) name,
416 (const void *) proc_pairs, ARRAY_SIZE(proc_pairs), sizeof(proc_pairs[0]),
417 __indirect_get_proc_compare);
419 return (pair) ? pair->proc : NULL;
422 #endif /* GLX_SHARED_GLAPI */
427 def printFunction(self
, func
, name
):
429 if func
.glx_rop
== ~
0:
430 print 'static %s' % (func
.return_type
)
431 print '%s( unsigned opcode, unsigned dim, %s )' % (func
.name
, func
.get_parameter_string())
434 if func
.has_different_protocol(name
):
435 if func
.return_type
== "void":
438 ret_string
= "return "
440 func_name
= func
.static_glx_name(name
)
441 print '#define %s %d' % (func
.opcode_vendor_name(name
), func
.glx_vendorpriv
)
442 print '%s gl%s(%s)' % (func
.return_type
, func_name
, func
.get_parameter_string())
444 print ' struct glx_context * const gc = __glXGetCurrentContext();'
446 print '#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)'
447 print ' if (gc->isDirect) {'
448 print ' const _glapi_proc *const disp_table = (_glapi_proc *)GET_DISPATCH();'
449 print ' PFNGL%sPROC p =' % (name
.upper())
450 print ' (PFNGL%sPROC) disp_table[%d];' % (name
.upper(), func
.offset
)
451 print ' %sp(%s);' % (ret_string
, func
.get_called_parameter_string())
458 print '#define %s %d' % (func
.opcode_name(), func
.opcode_value())
460 print '%s __indirect_gl%s(%s)' % (func
.return_type
, name
, func
.get_parameter_string())
464 if func
.glx_rop
!= 0 or func
.vectorequiv
!= None:
466 self
.printPixelFunction(func
)
468 self
.printRenderFunction(func
)
469 elif func
.glx_sop
!= 0 or func
.glx_vendorpriv
!= 0:
470 self
.printSingleFunction(func
, name
)
473 print "/* Missing GLX protocol for %s. */" % (name
)
479 def print_generic_function(self
, n
):
481 print """static FASTCALL NOINLINE void
482 generic_%u_byte( GLint rop, const void * ptr )
484 struct glx_context * const gc = __glXGetCurrentContext();
485 const GLuint cmdlen = %u;
487 emit_header(gc->pc, rop, cmdlen);
488 (void) memcpy((void *)(gc->pc + 4), ptr, %u);
490 if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }
492 """ % (n
, size
+ 4, size
)
496 def common_emit_one_arg(self
, p
, pc
, adjust
, extra_offset
):
500 src_ptr
= "&" + p
.name
503 print '(void) memset((void *)(%s + %u), 0, %s);' \
504 % (pc
, p
.offset
+ adjust
, p
.size_string() )
505 elif not extra_offset
:
506 print '(void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
507 % (pc
, p
.offset
+ adjust
, src_ptr
, p
.size_string() )
509 print '(void) memcpy((void *)(%s + %u + %s), (void *)(%s), %s);' \
510 % (pc
, p
.offset
+ adjust
, extra_offset
, src_ptr
, p
.size_string() )
512 def common_emit_args(self
, f
, pc
, adjust
, skip_vla
):
515 for p
in f
.parameterIterateGlxSend( not skip_vla
):
516 if p
.name
!= f
.img_reset
:
517 self
.common_emit_one_arg(p
, pc
, adjust
, extra_offset
)
519 if p
.is_variable_length():
520 temp
= p
.size_string()
522 extra_offset
+= " + %s" % (temp
)
529 def pixel_emit_args(self
, f
, pc
, large
):
530 """Emit the arguments for a pixel function. This differs from
531 common_emit_args in that pixel functions may require padding
532 be inserted (i.e., for the missing width field for
533 TexImage1D), and they may also require a 'NULL image' flag
534 be inserted before the image data."""
541 for param
in f
.parameterIterateGlxSend():
542 if not param
.is_image():
543 self
.common_emit_one_arg(param
, pc
, adjust
, None)
545 if f
.pad_after(param
):
546 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
+ param
.size()) + adjust
)
549 [dim
, width
, height
, depth
, extent
] = param
.get_dimensions()
556 print '(void) memset((void *)(%s + %u), 0, %s);' \
557 % (pc
, (param
.offset
- 4) + adjust
, param
.size_string() )
559 if param
.img_null_flag
:
561 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
- 4) + adjust
)
563 print '(void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (pc
, (param
.offset
- 4) + adjust
, param
.name
)
566 pixHeaderPtr
= "%s + %u" % (pc
, adjust
)
567 pcPtr
= "%s + %u" % (pc
, param
.offset
+ adjust
)
570 if param
.img_send_null
:
571 condition
= '(compsize > 0) && (%s != NULL)' % (param
.name
)
573 condition
= 'compsize > 0'
575 print 'if (%s) {' % (condition
)
576 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
)
578 print ' (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (pixHeaderPtr
, dim
, dim
)
581 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
)
586 def large_emit_begin(self
, f
, op_name
= None):
588 op_name
= f
.opcode_real_name()
590 print 'const GLint op = %s;' % (op_name
)
591 print 'const GLuint cmdlenLarge = cmdlen + 4;'
592 print 'GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);'
593 print '(void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);'
594 print '(void) memcpy((void *)(pc + 4), (void *)(&op), 4);'
598 def common_func_print_just_start(self
, f
, name
):
599 print ' struct glx_context * const gc = __glXGetCurrentContext();'
601 # The only reason that single and vendor private commands need
602 # a variable called 'dpy' is because they use the SyncHandle
603 # macro. For whatever brain-dead reason, that macro is hard-
604 # coded to use a variable called 'dpy' instead of taking a
607 # FIXME Simplify the logic related to skip_condition and
608 # FIXME condition_list in this function. Basically, remove
609 # FIXME skip_condition, and just append the "dpy != NULL" type
610 # FIXME condition to condition_list from the start. The only
611 # FIXME reason it's done in this confusing way now is to
612 # FIXME minimize the diffs in the generated code.
615 for p
in f
.parameterIterateOutputs():
616 if p
.is_image() and (p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP"):
617 print ' const __GLXattribute * const state = gc->client_state_private;'
620 print ' Display * const dpy = gc->currentDpy;'
621 skip_condition
= "dpy != NULL"
623 skip_condition
= "gc->currentDpy != NULL"
625 skip_condition
= None
628 if f
.return_type
!= 'void':
629 print ' %s retval = (%s) 0;' % (f
.return_type
, f
.return_type
)
632 if name
!= None and name
not in f
.glx_vendorpriv_names
:
633 print '#ifndef USE_XCB'
634 self
.emit_packet_size_calculation(f
, 0)
635 if name
!= None and name
not in f
.glx_vendorpriv_names
:
638 if f
.command_variable_length() != "":
639 print " if (0%s < 0) {" % f
.command_variable_length()
640 print " __glXSetError(gc, GL_INVALID_VALUE);"
641 if f
.return_type
!= 'void':
648 for p
in f
.parameterIterateCounters():
649 condition_list
.append( "%s >= 0" % (p
.name
) )
650 # 'counter' parameters cannot be negative
651 print " if (%s < 0) {" % p
.name
652 print " __glXSetError(gc, GL_INVALID_VALUE);"
653 if f
.return_type
!= 'void':
660 condition_list
.append( skip_condition
)
662 if len( condition_list
) > 0:
663 if len( condition_list
) > 1:
664 skip_condition
= "(%s)" % (string
.join( condition_list
, ") && (" ))
666 skip_condition
= "%s" % (condition_list
.pop(0))
668 print ' if (__builtin_expect(%s, 1)) {' % (skip_condition
)
674 def printSingleFunction(self
, f
, name
):
675 self
.common_func_print_just_start(f
, name
)
678 print ' printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
680 if name
not in f
.glx_vendorpriv_names
:
683 print '#ifdef USE_XCB'
685 print ' printf("\\tUsing XCB.\\n");'
686 print ' xcb_connection_t *c = XGetXCBConnection(dpy);'
687 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
688 xcb_name
= 'xcb_glx%s' % convertStringForXCB(name
)
693 for p
in f
.parameterIterator():
698 if p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP":
699 extra_iparams
.append("state->storePack.swapEndian")
701 extra_iparams
.append("0")
703 # Hardcode this in. lsb_first param (apparently always GL_FALSE)
704 # also present in GetPolygonStipple, but taken care of above.
705 if xcb_name
== "xcb_glx_read_pixels":
706 extra_iparams
.append("0")
708 iparams
.append(p
.name
)
711 xcb_request
= '%s(%s)' % (xcb_name
, ", ".join(["c", "gc->currentContextTag"] + iparams
+ extra_iparams
))
714 print ' %s_reply_t *reply = %s_reply(c, %s, NULL);' % (xcb_name
, xcb_name
, xcb_request
)
716 if output
.is_image():
717 [dim
, w
, h
, d
, junk
] = output
.get_dimensions()
718 if f
.dimensions_in_reply
:
725 print ' if (%s == 0) { %s = 1; }' % (h
, h
)
729 print ' if (%s == 0) { %s = 1; }' % (d
, d
)
731 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
)
733 if f
.reply_always_array
:
734 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
736 print ' /* the XXX_data_length() xcb function name is misleading, it returns the number */'
737 print ' /* of elements, not the length of the data part. A single element is embedded. */'
738 print ' if (%s_data_length(reply) == 1)' % (xcb_name
)
739 print ' (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output
.name
)
741 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
743 if f
.return_type
!= 'void':
744 print ' retval = reply->ret_val;'
745 print ' free(reply);'
747 print ' ' + xcb_request
+ ';'
749 # End of XCB specific.
752 if f
.parameters
!= []:
753 pc_decl
= "GLubyte const * pc ="
757 if name
in f
.glx_vendorpriv_names
:
758 print ' %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl
, f
.opcode_real_name(), f
.opcode_vendor_name(name
))
760 print ' %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl
, f
.opcode_name())
762 self
.common_emit_args(f
, "pc", 0, 0)
764 images
= f
.get_images()
768 o
= f
.command_fixed_length() - 4
769 print ' *(int32_t *)(pc + %u) = 0;' % (o
)
770 if img
.img_format
!= "GL_COLOR_INDEX" or img
.img_type
!= "GL_BITMAP":
771 print ' * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o
)
774 print ' * (int8_t *)(pc + %u) = %s;' % (o
+ 1, f
.img_reset
)
779 if f
.return_type
!= 'void':
780 return_name
= " retval"
781 return_str
= " retval = (%s)" % (f
.return_type
)
783 return_str
= " (void)"
787 for p
in f
.parameterIterateOutputs():
789 [dim
, w
, h
, d
, junk
] = p
.get_dimensions()
790 if f
.dimensions_in_reply
:
791 print " __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim
, p
.img_format
, p
.img_type
, p
.name
)
793 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
)
797 if f
.reply_always_array
:
802 # gl_parameter.size() returns the size
803 # of the entire data item. If the
804 # item is a fixed-size array, this is
805 # the size of the whole array. This
806 # is not what __glXReadReply wants. It
807 # wants the size of a single data
808 # element in the reply packet.
809 # Dividing by the array size (1 for
810 # non-arrays) gives us this.
812 s
= p
.size() / p
.get_element_count()
813 print " %s __glXReadReply(dpy, %s, %s, %s);" % (return_str
, s
, p
.name
, aa
)
817 # If a reply wasn't read to fill an output parameter,
818 # read a NULL reply to get the return value.
821 print " %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str
)
825 # Only emit the extra glFinish call for functions
826 # that don't already require a reply from the server.
827 print ' __indirect_glFinish();'
830 print ' printf( "Exit %%s.\\n", "gl%s" );' % (name
)
833 print ' UnlockDisplay(dpy); SyncHandle();'
835 if name
not in f
.glx_vendorpriv_names
:
836 print '#endif /* USE_XCB */'
839 print ' return%s;' % (return_name
)
843 def printPixelFunction(self
, f
):
844 if self
.pixel_stubs
.has_key( f
.name
):
845 # Normally gl_function::get_parameter_string could be
846 # used. However, this call needs to have the missing
847 # dimensions (e.g., a fake height value for
848 # glTexImage1D) added in.
851 for param
in f
.parameterIterateGlxSend():
855 p_string
+= ", " + param
.name
858 [dim
, junk
, junk
, junk
, junk
] = param
.get_dimensions()
860 if f
.pad_after(param
):
863 print ' %s(%s, %u%s );' % (self
.pixel_stubs
[f
.name
] , f
.opcode_name(), dim
, p_string
)
867 if self
.common_func_print_just_start(f
, None):
874 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
875 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
876 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
882 opcode
= f
.opcode_real_name()
884 print 'emit_header(gc->pc, %s, cmdlen);' % (opcode
)
886 self
.pixel_emit_args( f
, "gc->pc", 0 )
887 print 'gc->pc += cmdlen;'
888 print 'if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
894 self
.large_emit_begin(f
, opcode
)
895 self
.pixel_emit_args(f
, "pc", 1)
899 if trailer
: print trailer
903 def printRenderFunction(self
, f
):
904 # There is a class of GL functions that take a single pointer
905 # as a parameter. This pointer points to a fixed-size chunk
906 # of data, and the protocol for this functions is very
907 # regular. Since they are so regular and there are so many
908 # of them, special case them with generic functions. On
909 # x86, this saves about 26KB in the libGL.so binary.
911 if f
.variable_length_parameter() == None and len(f
.parameters
) == 1:
914 cmdlen
= f
.command_fixed_length()
915 if cmdlen
in self
.generic_sizes
:
916 print ' generic_%u_byte( %s, %s );' % (cmdlen
, f
.opcode_real_name(), p
.name
)
919 if self
.common_func_print_just_start(f
, None):
925 print 'printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
928 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
929 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
930 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
933 print 'emit_header(gc->pc, %s, cmdlen);' % (f
.opcode_real_name())
935 self
.common_emit_args(f
, "gc->pc", 4, 0)
936 print 'gc->pc += cmdlen;'
937 print 'if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
943 self
.large_emit_begin(f
)
944 self
.common_emit_args(f
, "pc", 8, 1)
946 p
= f
.variable_length_parameter()
947 print ' __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (p
.offset
+ 8, p
.name
, p
.size_string())
951 print '__indirect_glFinish();'
952 print 'printf( "Exit %%s.\\n", "gl%s" );' % (f
.name
)
954 if trailer
: print trailer
958 class PrintGlxProtoInit_c(gl_XML
.gl_print_base
):
960 gl_XML
.gl_print_base
.__init
__(self
)
962 self
.name
= "glX_proto_send.py (from Mesa)"
963 self
.license
= license
.bsd_license_template
% ( \
964 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
965 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
969 def printRealHeader(self
):
971 * \\file indirect_init.c
972 * Initialize indirect rendering dispatch table.
974 * \\author Kevin E. Martin <kevin@precisioninsight.com>
975 * \\author Brian Paul <brian@precisioninsight.com>
976 * \\author Ian Romanick <idr@us.ibm.com>
979 #include "indirect_init.h"
980 #include "indirect.h"
984 #ifndef GLX_USE_APPLEGL
987 * No-op function used to initialize functions that have no GLX protocol
990 static int NoOp(void)
996 * Create and initialize a new GL dispatch table. The table is initialized
997 * with GLX indirect rendering protocol functions.
999 struct _glapi_table * __glXNewIndirectAPI( void )
1006 entries = _glapi_get_dispatch_table_size();
1007 table = malloc(entries * sizeof(_glapi_proc));
1011 /* first, set all entries to point to no-op functions */
1012 for (i = 0; i < entries; i++) {
1013 table[i] = (_glapi_proc) NoOp;
1016 /* now, initialize the entries we understand */"""
1018 def printRealFooter(self
):
1020 return (struct _glapi_table *) table;
1028 def printBody(self
, api
):
1029 for [name
, number
] in api
.categoryIterate():
1031 preamble
= '\n /* %3u. %s */\n' % (int(number
), name
)
1033 preamble
= '\n /* %s */\n' % (name
)
1035 for func
in api
.functionIterateByCategory(name
):
1036 if func
.client_supported_for_indirect():
1042 print ' table[{offset}] = (_glapi_proc) __indirect_gl{name};'.format(name
= func
.name
, offset
= func
.offset
)
1044 print ' o = _glapi_get_proc_offset("gl{0}");'.format(func
.name
)
1045 print ' assert(o > 0);'
1046 print ' table[o] = (_glapi_proc) __indirect_gl{0};'.format(func
.name
)
1051 class PrintGlxProtoInit_h(gl_XML
.gl_print_base
):
1053 gl_XML
.gl_print_base
.__init
__(self
)
1055 self
.name
= "glX_proto_send.py (from Mesa)"
1056 self
.license
= license
.bsd_license_template
% ( \
1057 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
1058 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
1059 self
.header_tag
= "_INDIRECT_H_"
1061 self
.last_category
= ""
1065 def printRealHeader(self
):
1068 * Prototypes for indirect rendering functions.
1070 * \\author Kevin E. Martin <kevin@precisioninsight.com>
1071 * \\author Ian Romanick <idr@us.ibm.com>
1074 self
.printFastcall()
1075 self
.printNoinline()
1078 #include <X11/Xfuncproto.h>
1079 #include "glxclient.h"
1081 extern _X_HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
1082 void * dest, GLboolean reply_is_always_array );
1084 extern _X_HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
1085 struct glx_context * gc, unsigned max_dim, GLint width, GLint height,
1086 GLint depth, GLenum format, GLenum type, void * dest,
1087 GLboolean dimensions_in_reply );
1089 extern _X_HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
1090 struct glx_context * gc, GLint sop, GLint cmdlen );
1092 extern _X_HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
1093 struct glx_context * gc, GLint code, GLint vop, GLint cmdlen );
1097 def printBody(self
, api
):
1098 for func
in api
.functionIterateGlx():
1099 params
= func
.get_parameter_string()
1101 print 'extern _X_HIDDEN %s __indirect_gl%s(%s);' % (func
.return_type
, func
.name
, params
)
1103 for n
in func
.entry_points
:
1104 if func
.has_different_protocol(n
):
1105 asdf
= func
.static_glx_name(n
)
1106 if asdf
not in func
.static_entry_points
:
1107 print 'extern _X_HIDDEN %s gl%s(%s);' % (func
.return_type
, asdf
, params
)
1108 # give it a easy-to-remember name
1109 if func
.client_handcode
:
1110 print '#define gl_dispatch_stub_%s gl%s' % (n
, asdf
)
1112 print 'GLAPI %s GLAPIENTRY gl%s(%s);' % (func
.return_type
, asdf
, params
)
1117 print '#ifdef GLX_SHARED_GLAPI'
1118 print 'extern _X_HIDDEN void (*__indirect_get_proc_address(const char *name))(void);'
1123 """Parse input and returned a parsed namespace."""
1124 parser
= argparse
.ArgumentParser()
1125 parser
.add_argument('-f',
1126 default
='gl_API.xml',
1128 help='An XML file describing an API')
1129 parser
.add_argument('-m',
1132 choices
=frozenset(['proto', 'init_c', 'init_h']),
1133 help='which file to generate')
1134 parser
.add_argument('-d',
1135 action
='store_true',
1137 help='turn debug mode on.')
1138 return parser
.parse_args()
1142 """Main function."""
1145 if args
.mode
== "proto":
1146 printer
= PrintGlxProtoStubs()
1147 elif args
.mode
== "init_c":
1148 printer
= PrintGlxProtoInit_c()
1149 elif args
.mode
== "init_h":
1150 printer
= PrintGlxProtoInit_h()
1152 printer
.debug
= args
.debug
1153 api
= gl_XML
.parse_GL_API(args
.filename
, glX_XML
.glx_item_factory())
1155 printer
.Print( api
)
1158 if __name__
== '__main__':