8b3d8d756b8d4c0a55f03625cd16b999310e44a3
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>'
180 print '#define __GLX_PAD(n) (((n) + 3) & ~3)'
186 print 'static _X_INLINE int safe_add(int a, int b)'
188 print ' if (a < 0 || b < 0) return -1;'
189 print ' if (INT_MAX - a < b) return -1;'
190 print ' return a + b;'
192 print 'static _X_INLINE int safe_mul(int a, int b)'
194 print ' if (a < 0 || b < 0) return -1;'
195 print ' if (a == 0 || b == 0) return 0;'
196 print ' if (a > INT_MAX / b) return -1;'
197 print ' return a * b;'
199 print 'static _X_INLINE int safe_pad(int a)'
202 print ' if (a < 0) return -1;'
203 print ' if ((ret = safe_add(a, 3)) < 0) return -1;'
204 print ' return ret & (GLuint)~3;'
208 print '#ifndef __GNUC__'
209 print '# define __builtin_expect(x, y) x'
212 print '/* If the size and opcode values are known at compile-time, this will, on'
213 print ' * x86 at least, emit them with a single instruction.'
215 print '#define emit_header(dest, op, size) \\'
216 print ' do { union { short s[2]; int i; } temp; \\'
217 print ' temp.s[0] = (size); temp.s[1] = (op); \\'
218 print ' *((int *)(dest)) = temp.i; } while(0)'
220 print """NOINLINE CARD32
221 __glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array )
223 xGLXSingleReply reply;
225 (void) _XReply(dpy, (xReply *) & reply, 0, False);
227 if ((reply.length > 0) || reply_is_always_array) {
228 const GLint bytes = (reply_is_always_array)
229 ? (4 * reply.length) : (reply.size * size);
230 const GLint extra = 4 - (bytes & 3);
232 _XRead(dpy, dest, bytes);
234 _XEatData(dpy, extra);
238 (void) memcpy( dest, &(reply.pad3), size);
246 __glXReadPixelReply( Display *dpy, struct glx_context * gc, unsigned max_dim,
247 GLint width, GLint height, GLint depth, GLenum format, GLenum type,
248 void * dest, GLboolean dimensions_in_reply )
250 xGLXSingleReply reply;
253 (void) _XReply(dpy, (xReply *) & reply, 0, False);
255 if ( dimensions_in_reply ) {
260 if ((height == 0) || (max_dim < 2)) { height = 1; }
261 if ((depth == 0) || (max_dim < 3)) { depth = 1; }
264 size = reply.length * 4;
266 void * buf = malloc( size );
269 _XEatData(dpy, size);
270 __glXSetError(gc, GL_OUT_OF_MEMORY);
273 const GLint extra = 4 - (size & 3);
275 _XRead(dpy, buf, size);
277 _XEatData(dpy, extra);
280 __glEmptyImage(gc, 3, width, height, depth, format, type,
287 #define X_GLXSingle 0
289 NOINLINE FASTCALL GLubyte *
290 __glXSetupSingleRequest( struct glx_context * gc, GLint sop, GLint cmdlen )
293 Display * const dpy = gc->currentDpy;
295 (void) __glXFlushRenderBuffer(gc, gc->pc);
297 GetReqExtra(GLXSingle, cmdlen, req);
298 req->reqType = gc->majorOpcode;
299 req->contextTag = gc->currentContextTag;
301 return (GLubyte *)(req) + sz_xGLXSingleReq;
304 NOINLINE FASTCALL GLubyte *
305 __glXSetupVendorRequest( struct glx_context * gc, GLint code, GLint vop, GLint cmdlen )
307 xGLXVendorPrivateReq * req;
308 Display * const dpy = gc->currentDpy;
310 (void) __glXFlushRenderBuffer(gc, gc->pc);
312 GetReqExtra(GLXVendorPrivate, cmdlen, req);
313 req->reqType = gc->majorOpcode;
315 req->vendorCode = vop;
316 req->contextTag = gc->currentContextTag;
317 return (GLubyte *)(req) + sz_xGLXVendorPrivateReq;
320 const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 };
322 #define zero (__glXDefaultPixelStore+0)
323 #define one (__glXDefaultPixelStore+8)
324 #define default_pixel_store_1D (__glXDefaultPixelStore+4)
325 #define default_pixel_store_1D_size 20
326 #define default_pixel_store_2D (__glXDefaultPixelStore+4)
327 #define default_pixel_store_2D_size 20
328 #define default_pixel_store_3D (__glXDefaultPixelStore+0)
329 #define default_pixel_store_3D_size 36
330 #define default_pixel_store_4D (__glXDefaultPixelStore+0)
331 #define default_pixel_store_4D_size 36
334 for size
in self
.generic_sizes
:
335 self
.print_generic_function(size
)
339 def printBody(self
, api
):
341 self
.pixel_stubs
= {}
344 for func
in api
.functionIterateGlx():
345 if func
.client_handcode
: continue
347 # If the function is a pixel function with a certain
348 # GLX protocol signature, create a fake stub function
349 # for it. For example, create a single stub function
350 # that is used to implement both glTexImage1D and
353 if func
.glx_rop
!= 0:
355 for image
in func
.get_images():
356 if image
.img_pad_dimensions
:
362 [h
, n
] = hash_pixel_function(func
)
365 self
.pixel_stubs
[ func
.name
] = n
366 if h
not in generated_stubs
:
367 generated_stubs
.append(h
)
369 fake_func
= glx_pixel_function_stub( func
, n
)
370 self
.printFunction(fake_func
, fake_func
.name
)
373 self
.printFunction(func
, func
.name
)
374 if func
.glx_sop
and func
.glx_vendorpriv
:
375 self
.printFunction(func
, func
.glx_vendorpriv_names
[0])
377 self
.printGetProcAddress(api
)
380 def printGetProcAddress(self
, api
):
382 for func
in api
.functionIterateGlx():
383 for n
in func
.entry_points
:
384 if func
.has_different_protocol(n
):
385 procs
[n
] = func
.static_glx_name(n
)
388 #ifdef GLX_SHARED_GLAPI
390 static const struct proc_pair
394 } proc_pairs[%d] = {""" % len(procs
)
397 for i
in xrange(len(names
)):
398 comma
= ',' if i
< len(names
) - 1 else ''
399 print ' { "%s", (_glapi_proc) gl%s }%s' % (names
[i
], procs
[names
[i
]], comma
)
403 __indirect_get_proc_compare(const void *key, const void *memb)
405 const struct proc_pair *pair = (const struct proc_pair *) memb;
406 return strcmp((const char *) key, pair->name);
410 __indirect_get_proc_address(const char *name)
412 const struct proc_pair *pair;
417 pair = (const struct proc_pair *) bsearch((const void *) name,
418 (const void *) proc_pairs, ARRAY_SIZE(proc_pairs), sizeof(proc_pairs[0]),
419 __indirect_get_proc_compare);
421 return (pair) ? pair->proc : NULL;
424 #endif /* GLX_SHARED_GLAPI */
429 def printFunction(self
, func
, name
):
431 if func
.glx_rop
== ~
0:
432 print 'static %s' % (func
.return_type
)
433 print '%s( unsigned opcode, unsigned dim, %s )' % (func
.name
, func
.get_parameter_string())
436 if func
.has_different_protocol(name
):
437 if func
.return_type
== "void":
440 ret_string
= "return "
442 func_name
= func
.static_glx_name(name
)
443 print '#define %s %d' % (func
.opcode_vendor_name(name
), func
.glx_vendorpriv
)
444 print '%s gl%s(%s)' % (func
.return_type
, func_name
, func
.get_parameter_string())
446 print ' struct glx_context * const gc = __glXGetCurrentContext();'
448 print '#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)'
449 print ' if (gc->isDirect) {'
450 print ' const _glapi_proc *const disp_table = (_glapi_proc *)GET_DISPATCH();'
451 print ' PFNGL%sPROC p =' % (name
.upper())
452 print ' (PFNGL%sPROC) disp_table[%d];' % (name
.upper(), func
.offset
)
453 print ' %sp(%s);' % (ret_string
, func
.get_called_parameter_string())
460 print '#define %s %d' % (func
.opcode_name(), func
.opcode_value())
462 print '%s __indirect_gl%s(%s)' % (func
.return_type
, name
, func
.get_parameter_string())
466 if func
.glx_rop
!= 0 or func
.vectorequiv
!= None:
468 self
.printPixelFunction(func
)
470 self
.printRenderFunction(func
)
471 elif func
.glx_sop
!= 0 or func
.glx_vendorpriv
!= 0:
472 self
.printSingleFunction(func
, name
)
475 print "/* Missing GLX protocol for %s. */" % (name
)
481 def print_generic_function(self
, n
):
483 print """static FASTCALL NOINLINE void
484 generic_%u_byte( GLint rop, const void * ptr )
486 struct glx_context * const gc = __glXGetCurrentContext();
487 const GLuint cmdlen = %u;
489 emit_header(gc->pc, rop, cmdlen);
490 (void) memcpy((void *)(gc->pc + 4), ptr, %u);
492 if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }
494 """ % (n
, size
+ 4, size
)
498 def common_emit_one_arg(self
, p
, pc
, adjust
, extra_offset
):
502 src_ptr
= "&" + p
.name
505 print '(void) memset((void *)(%s + %u), 0, %s);' \
506 % (pc
, p
.offset
+ adjust
, p
.size_string() )
507 elif not extra_offset
:
508 print '(void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
509 % (pc
, p
.offset
+ adjust
, src_ptr
, p
.size_string() )
511 print '(void) memcpy((void *)(%s + %u + %s), (void *)(%s), %s);' \
512 % (pc
, p
.offset
+ adjust
, extra_offset
, src_ptr
, p
.size_string() )
514 def common_emit_args(self
, f
, pc
, adjust
, skip_vla
):
517 for p
in f
.parameterIterateGlxSend( not skip_vla
):
518 if p
.name
!= f
.img_reset
:
519 self
.common_emit_one_arg(p
, pc
, adjust
, extra_offset
)
521 if p
.is_variable_length():
522 temp
= p
.size_string()
524 extra_offset
+= " + %s" % (temp
)
531 def pixel_emit_args(self
, f
, pc
, large
):
532 """Emit the arguments for a pixel function. This differs from
533 common_emit_args in that pixel functions may require padding
534 be inserted (i.e., for the missing width field for
535 TexImage1D), and they may also require a 'NULL image' flag
536 be inserted before the image data."""
543 for param
in f
.parameterIterateGlxSend():
544 if not param
.is_image():
545 self
.common_emit_one_arg(param
, pc
, adjust
, None)
547 if f
.pad_after(param
):
548 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
+ param
.size()) + adjust
)
551 [dim
, width
, height
, depth
, extent
] = param
.get_dimensions()
558 print '(void) memset((void *)(%s + %u), 0, %s);' \
559 % (pc
, (param
.offset
- 4) + adjust
, param
.size_string() )
561 if param
.img_null_flag
:
563 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
- 4) + adjust
)
565 print '(void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (pc
, (param
.offset
- 4) + adjust
, param
.name
)
568 pixHeaderPtr
= "%s + %u" % (pc
, adjust
)
569 pcPtr
= "%s + %u" % (pc
, param
.offset
+ adjust
)
572 if param
.img_send_null
:
573 condition
= '(compsize > 0) && (%s != NULL)' % (param
.name
)
575 condition
= 'compsize > 0'
577 print 'if (%s) {' % (condition
)
578 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
)
580 print ' (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (pixHeaderPtr
, dim
, dim
)
583 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
)
588 def large_emit_begin(self
, f
, op_name
= None):
590 op_name
= f
.opcode_real_name()
592 print 'const GLint op = %s;' % (op_name
)
593 print 'const GLuint cmdlenLarge = cmdlen + 4;'
594 print 'GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);'
595 print '(void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);'
596 print '(void) memcpy((void *)(pc + 4), (void *)(&op), 4);'
600 def common_func_print_just_start(self
, f
, name
):
601 print ' struct glx_context * const gc = __glXGetCurrentContext();'
603 # The only reason that single and vendor private commands need
604 # a variable called 'dpy' is because they use the SyncHandle
605 # macro. For whatever brain-dead reason, that macro is hard-
606 # coded to use a variable called 'dpy' instead of taking a
609 # FIXME Simplify the logic related to skip_condition and
610 # FIXME condition_list in this function. Basically, remove
611 # FIXME skip_condition, and just append the "dpy != NULL" type
612 # FIXME condition to condition_list from the start. The only
613 # FIXME reason it's done in this confusing way now is to
614 # FIXME minimize the diffs in the generated code.
617 for p
in f
.parameterIterateOutputs():
618 if p
.is_image() and (p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP"):
619 print ' const __GLXattribute * const state = gc->client_state_private;'
622 print ' Display * const dpy = gc->currentDpy;'
623 skip_condition
= "dpy != NULL"
625 skip_condition
= "gc->currentDpy != NULL"
627 skip_condition
= None
630 if f
.return_type
!= 'void':
631 print ' %s retval = (%s) 0;' % (f
.return_type
, f
.return_type
)
634 if name
!= None and name
not in f
.glx_vendorpriv_names
:
635 print '#ifndef USE_XCB'
636 self
.emit_packet_size_calculation(f
, 0)
637 if name
!= None and name
not in f
.glx_vendorpriv_names
:
641 for p
in f
.parameterIterateCounters():
642 condition_list
.append( "%s >= 0" % (p
.name
) )
643 # 'counter' parameters cannot be negative
644 print " if (%s < 0) {" % p
.name
645 print " __glXSetError(gc, GL_INVALID_VALUE);"
646 if f
.return_type
!= 'void':
653 condition_list
.append( skip_condition
)
655 if len( condition_list
) > 0:
656 if len( condition_list
) > 1:
657 skip_condition
= "(%s)" % (string
.join( condition_list
, ") && (" ))
659 skip_condition
= "%s" % (condition_list
.pop(0))
661 print ' if (__builtin_expect(%s, 1)) {' % (skip_condition
)
667 def printSingleFunction(self
, f
, name
):
668 self
.common_func_print_just_start(f
, name
)
671 print ' printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
673 if name
not in f
.glx_vendorpriv_names
:
676 print '#ifdef USE_XCB'
678 print ' printf("\\tUsing XCB.\\n");'
679 print ' xcb_connection_t *c = XGetXCBConnection(dpy);'
680 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
681 xcb_name
= 'xcb_glx%s' % convertStringForXCB(name
)
686 for p
in f
.parameterIterator():
691 if p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP":
692 extra_iparams
.append("state->storePack.swapEndian")
694 extra_iparams
.append("0")
696 # Hardcode this in. lsb_first param (apparently always GL_FALSE)
697 # also present in GetPolygonStipple, but taken care of above.
698 if xcb_name
== "xcb_glx_read_pixels":
699 extra_iparams
.append("0")
701 iparams
.append(p
.name
)
704 xcb_request
= '%s(%s)' % (xcb_name
, ", ".join(["c", "gc->currentContextTag"] + iparams
+ extra_iparams
))
707 print ' %s_reply_t *reply = %s_reply(c, %s, NULL);' % (xcb_name
, xcb_name
, xcb_request
)
709 if output
.is_image():
710 [dim
, w
, h
, d
, junk
] = output
.get_dimensions()
711 if f
.dimensions_in_reply
:
718 print ' if (%s == 0) { %s = 1; }' % (h
, h
)
722 print ' if (%s == 0) { %s = 1; }' % (d
, d
)
724 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
)
726 if f
.reply_always_array
:
727 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
729 print ' /* the XXX_data_length() xcb function name is misleading, it returns the number */'
730 print ' /* of elements, not the length of the data part. A single element is embedded. */'
731 print ' if (%s_data_length(reply) == 1)' % (xcb_name
)
732 print ' (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output
.name
)
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 if f
.return_type
!= 'void':
737 print ' retval = reply->ret_val;'
738 print ' free(reply);'
740 print ' ' + xcb_request
+ ';'
742 # End of XCB specific.
745 if f
.parameters
!= []:
746 pc_decl
= "GLubyte const * pc ="
750 if name
in f
.glx_vendorpriv_names
:
751 print ' %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl
, f
.opcode_real_name(), f
.opcode_vendor_name(name
))
753 print ' %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl
, f
.opcode_name())
755 self
.common_emit_args(f
, "pc", 0, 0)
757 images
= f
.get_images()
761 o
= f
.command_fixed_length() - 4
762 print ' *(int32_t *)(pc + %u) = 0;' % (o
)
763 if img
.img_format
!= "GL_COLOR_INDEX" or img
.img_type
!= "GL_BITMAP":
764 print ' * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o
)
767 print ' * (int8_t *)(pc + %u) = %s;' % (o
+ 1, f
.img_reset
)
772 if f
.return_type
!= 'void':
773 return_name
= " retval"
774 return_str
= " retval = (%s)" % (f
.return_type
)
776 return_str
= " (void)"
780 for p
in f
.parameterIterateOutputs():
782 [dim
, w
, h
, d
, junk
] = p
.get_dimensions()
783 if f
.dimensions_in_reply
:
784 print " __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim
, p
.img_format
, p
.img_type
, p
.name
)
786 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
)
790 if f
.reply_always_array
:
795 # gl_parameter.size() returns the size
796 # of the entire data item. If the
797 # item is a fixed-size array, this is
798 # the size of the whole array. This
799 # is not what __glXReadReply wants. It
800 # wants the size of a single data
801 # element in the reply packet.
802 # Dividing by the array size (1 for
803 # non-arrays) gives us this.
805 s
= p
.size() / p
.get_element_count()
806 print " %s __glXReadReply(dpy, %s, %s, %s);" % (return_str
, s
, p
.name
, aa
)
810 # If a reply wasn't read to fill an output parameter,
811 # read a NULL reply to get the return value.
814 print " %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str
)
818 # Only emit the extra glFinish call for functions
819 # that don't already require a reply from the server.
820 print ' __indirect_glFinish();'
823 print ' printf( "Exit %%s.\\n", "gl%s" );' % (name
)
826 print ' UnlockDisplay(dpy); SyncHandle();'
828 if name
not in f
.glx_vendorpriv_names
:
829 print '#endif /* USE_XCB */'
832 print ' return%s;' % (return_name
)
836 def printPixelFunction(self
, f
):
837 if self
.pixel_stubs
.has_key( f
.name
):
838 # Normally gl_function::get_parameter_string could be
839 # used. However, this call needs to have the missing
840 # dimensions (e.g., a fake height value for
841 # glTexImage1D) added in.
844 for param
in f
.parameterIterateGlxSend():
848 p_string
+= ", " + param
.name
851 [dim
, junk
, junk
, junk
, junk
] = param
.get_dimensions()
853 if f
.pad_after(param
):
856 print ' %s(%s, %u%s );' % (self
.pixel_stubs
[f
.name
] , f
.opcode_name(), dim
, p_string
)
860 if self
.common_func_print_just_start(f
, None):
867 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
868 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
869 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
875 opcode
= f
.opcode_real_name()
877 print 'emit_header(gc->pc, %s, cmdlen);' % (opcode
)
879 self
.pixel_emit_args( f
, "gc->pc", 0 )
880 print 'gc->pc += cmdlen;'
881 print 'if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
887 self
.large_emit_begin(f
, opcode
)
888 self
.pixel_emit_args(f
, "pc", 1)
892 if trailer
: print trailer
896 def printRenderFunction(self
, f
):
897 # There is a class of GL functions that take a single pointer
898 # as a parameter. This pointer points to a fixed-size chunk
899 # of data, and the protocol for this functions is very
900 # regular. Since they are so regular and there are so many
901 # of them, special case them with generic functions. On
902 # x86, this saves about 26KB in the libGL.so binary.
904 if f
.variable_length_parameter() == None and len(f
.parameters
) == 1:
907 cmdlen
= f
.command_fixed_length()
908 if cmdlen
in self
.generic_sizes
:
909 print ' generic_%u_byte( %s, %s );' % (cmdlen
, f
.opcode_real_name(), p
.name
)
912 if self
.common_func_print_just_start(f
, None):
918 print 'printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
921 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
922 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
923 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
926 print 'emit_header(gc->pc, %s, cmdlen);' % (f
.opcode_real_name())
928 self
.common_emit_args(f
, "gc->pc", 4, 0)
929 print 'gc->pc += cmdlen;'
930 print 'if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
936 self
.large_emit_begin(f
)
937 self
.common_emit_args(f
, "pc", 8, 1)
939 p
= f
.variable_length_parameter()
940 print ' __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (p
.offset
+ 8, p
.name
, p
.size_string())
944 print '__indirect_glFinish();'
945 print 'printf( "Exit %%s.\\n", "gl%s" );' % (f
.name
)
947 if trailer
: print trailer
951 class PrintGlxProtoInit_c(gl_XML
.gl_print_base
):
953 gl_XML
.gl_print_base
.__init
__(self
)
955 self
.name
= "glX_proto_send.py (from Mesa)"
956 self
.license
= license
.bsd_license_template
% ( \
957 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
958 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
962 def printRealHeader(self
):
964 * \\file indirect_init.c
965 * Initialize indirect rendering dispatch table.
967 * \\author Kevin E. Martin <kevin@precisioninsight.com>
968 * \\author Brian Paul <brian@precisioninsight.com>
969 * \\author Ian Romanick <idr@us.ibm.com>
972 #include "indirect_init.h"
973 #include "indirect.h"
977 #ifndef GLX_USE_APPLEGL
980 * No-op function used to initialize functions that have no GLX protocol
983 static int NoOp(void)
989 * Create and initialize a new GL dispatch table. The table is initialized
990 * with GLX indirect rendering protocol functions.
992 struct _glapi_table * __glXNewIndirectAPI( void )
999 entries = _glapi_get_dispatch_table_size();
1000 table = malloc(entries * sizeof(_glapi_proc));
1004 /* first, set all entries to point to no-op functions */
1005 for (i = 0; i < entries; i++) {
1006 table[i] = (_glapi_proc) NoOp;
1009 /* now, initialize the entries we understand */"""
1011 def printRealFooter(self
):
1013 return (struct _glapi_table *) table;
1021 def printBody(self
, api
):
1022 for [name
, number
] in api
.categoryIterate():
1024 preamble
= '\n /* %3u. %s */\n' % (int(number
), name
)
1026 preamble
= '\n /* %s */\n' % (name
)
1028 for func
in api
.functionIterateByCategory(name
):
1029 if func
.client_supported_for_indirect():
1035 print ' table[{offset}] = (_glapi_proc) __indirect_gl{name};'.format(name
= func
.name
, offset
= func
.offset
)
1037 print ' o = _glapi_get_proc_offset("gl{0}");'.format(func
.name
)
1038 print ' assert(o > 0);'
1039 print ' table[o] = (_glapi_proc) __indirect_gl{0};'.format(func
.name
)
1044 class PrintGlxProtoInit_h(gl_XML
.gl_print_base
):
1046 gl_XML
.gl_print_base
.__init
__(self
)
1048 self
.name
= "glX_proto_send.py (from Mesa)"
1049 self
.license
= license
.bsd_license_template
% ( \
1050 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
1051 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
1052 self
.header_tag
= "_INDIRECT_H_"
1054 self
.last_category
= ""
1058 def printRealHeader(self
):
1061 * Prototypes for indirect rendering functions.
1063 * \\author Kevin E. Martin <kevin@precisioninsight.com>
1064 * \\author Ian Romanick <idr@us.ibm.com>
1067 self
.printFastcall()
1068 self
.printNoinline()
1071 #include <X11/Xfuncproto.h>
1072 #include "glxclient.h"
1074 extern _X_HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
1075 void * dest, GLboolean reply_is_always_array );
1077 extern _X_HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
1078 struct glx_context * gc, unsigned max_dim, GLint width, GLint height,
1079 GLint depth, GLenum format, GLenum type, void * dest,
1080 GLboolean dimensions_in_reply );
1082 extern _X_HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
1083 struct glx_context * gc, GLint sop, GLint cmdlen );
1085 extern _X_HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
1086 struct glx_context * gc, GLint code, GLint vop, GLint cmdlen );
1090 def printBody(self
, api
):
1091 for func
in api
.functionIterateGlx():
1092 params
= func
.get_parameter_string()
1094 print 'extern _X_HIDDEN %s __indirect_gl%s(%s);' % (func
.return_type
, func
.name
, params
)
1096 for n
in func
.entry_points
:
1097 if func
.has_different_protocol(n
):
1098 asdf
= func
.static_glx_name(n
)
1099 if asdf
not in func
.static_entry_points
:
1100 print 'extern _X_HIDDEN %s gl%s(%s);' % (func
.return_type
, asdf
, params
)
1101 # give it a easy-to-remember name
1102 if func
.client_handcode
:
1103 print '#define gl_dispatch_stub_%s gl%s' % (n
, asdf
)
1105 print 'GLAPI %s GLAPIENTRY gl%s(%s);' % (func
.return_type
, asdf
, params
)
1110 print '#ifdef GLX_SHARED_GLAPI'
1111 print 'extern _X_HIDDEN void (*__indirect_get_proc_address(const char *name))(void);'
1116 """Parse input and returned a parsed namespace."""
1117 parser
= argparse
.ArgumentParser()
1118 parser
.add_argument('-f',
1119 default
='gl_API.xml',
1121 help='An XML file describing an API')
1122 parser
.add_argument('-m',
1125 choices
=frozenset(['proto', 'init_c', 'init_h']),
1126 help='which file to generate')
1127 parser
.add_argument('-d',
1128 action
='store_true',
1130 help='turn debug mode on.')
1131 return parser
.parse_args()
1135 """Main function."""
1138 if args
.mode
== "proto":
1139 printer
= PrintGlxProtoStubs()
1140 elif args
.mode
== "init_c":
1141 printer
= PrintGlxProtoInit_c()
1142 elif args
.mode
== "init_h":
1143 printer
= PrintGlxProtoInit_h()
1145 printer
.debug
= args
.debug
1146 api
= gl_XML
.parse_GL_API(args
.filename
, glX_XML
.glx_item_factory())
1148 printer
.Print( api
)
1151 if __name__
== '__main__':