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>'
179 print '#define __GLX_PAD(n) (((n) + 3) & ~3)'
184 print '#ifndef __GNUC__'
185 print '# define __builtin_expect(x, y) x'
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.'
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)'
196 print """NOINLINE CARD32
197 __glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array )
199 xGLXSingleReply reply;
201 (void) _XReply(dpy, (xReply *) & reply, 0, False);
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);
208 _XRead(dpy, dest, bytes);
210 _XEatData(dpy, extra);
214 (void) memcpy( dest, &(reply.pad3), size);
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 )
226 xGLXSingleReply reply;
229 (void) _XReply(dpy, (xReply *) & reply, 0, False);
231 if ( dimensions_in_reply ) {
236 if ((height == 0) || (max_dim < 2)) { height = 1; }
237 if ((depth == 0) || (max_dim < 3)) { depth = 1; }
240 size = reply.length * 4;
242 void * buf = malloc( size );
245 _XEatData(dpy, size);
246 __glXSetError(gc, GL_OUT_OF_MEMORY);
249 const GLint extra = 4 - (size & 3);
251 _XRead(dpy, buf, size);
253 _XEatData(dpy, extra);
256 __glEmptyImage(gc, 3, width, height, depth, format, type,
263 #define X_GLXSingle 0
265 NOINLINE FASTCALL GLubyte *
266 __glXSetupSingleRequest( struct glx_context * gc, GLint sop, GLint cmdlen )
269 Display * const dpy = gc->currentDpy;
271 (void) __glXFlushRenderBuffer(gc, gc->pc);
273 GetReqExtra(GLXSingle, cmdlen, req);
274 req->reqType = gc->majorOpcode;
275 req->contextTag = gc->currentContextTag;
277 return (GLubyte *)(req) + sz_xGLXSingleReq;
280 NOINLINE FASTCALL GLubyte *
281 __glXSetupVendorRequest( struct glx_context * gc, GLint code, GLint vop, GLint cmdlen )
283 xGLXVendorPrivateReq * req;
284 Display * const dpy = gc->currentDpy;
286 (void) __glXFlushRenderBuffer(gc, gc->pc);
288 GetReqExtra(GLXVendorPrivate, cmdlen, req);
289 req->reqType = gc->majorOpcode;
291 req->vendorCode = vop;
292 req->contextTag = gc->currentContextTag;
293 return (GLubyte *)(req) + sz_xGLXVendorPrivateReq;
296 const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 };
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
310 for size
in self
.generic_sizes
:
311 self
.print_generic_function(size
)
315 def printBody(self
, api
):
317 self
.pixel_stubs
= {}
320 for func
in api
.functionIterateGlx():
321 if func
.client_handcode
: continue
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
329 if func
.glx_rop
!= 0:
331 for image
in func
.get_images():
332 if image
.img_pad_dimensions
:
338 [h
, n
] = hash_pixel_function(func
)
341 self
.pixel_stubs
[ func
.name
] = n
342 if h
not in generated_stubs
:
343 generated_stubs
.append(h
)
345 fake_func
= glx_pixel_function_stub( func
, n
)
346 self
.printFunction(fake_func
, fake_func
.name
)
349 self
.printFunction(func
, func
.name
)
350 if func
.glx_sop
and func
.glx_vendorpriv
:
351 self
.printFunction(func
, func
.glx_vendorpriv_names
[0])
353 self
.printGetProcAddress(api
)
356 def printGetProcAddress(self
, api
):
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
)
364 #ifdef GLX_SHARED_GLAPI
366 static const struct proc_pair
370 } proc_pairs[%d] = {""" % len(procs
)
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
)
379 __indirect_get_proc_compare(const void *key, const void *memb)
381 const struct proc_pair *pair = (const struct proc_pair *) memb;
382 return strcmp((const char *) key, pair->name);
386 __indirect_get_proc_address(const char *name)
388 const struct proc_pair *pair;
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);
397 return (pair) ? pair->proc : NULL;
400 #endif /* GLX_SHARED_GLAPI */
405 def printFunction(self
, func
, name
):
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())
412 if func
.has_different_protocol(name
):
413 if func
.return_type
== "void":
416 ret_string
= "return "
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())
422 print ' struct glx_context * const gc = __glXGetCurrentContext();'
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())
436 print '#define %s %d' % (func
.opcode_name(), func
.opcode_value())
438 print '%s __indirect_gl%s(%s)' % (func
.return_type
, name
, func
.get_parameter_string())
442 if func
.glx_rop
!= 0 or func
.vectorequiv
!= None:
444 self
.printPixelFunction(func
)
446 self
.printRenderFunction(func
)
447 elif func
.glx_sop
!= 0 or func
.glx_vendorpriv
!= 0:
448 self
.printSingleFunction(func
, name
)
451 print "/* Missing GLX protocol for %s. */" % (name
)
457 def print_generic_function(self
, n
):
459 print """static FASTCALL NOINLINE void
460 generic_%u_byte( GLint rop, const void * ptr )
462 struct glx_context * const gc = __glXGetCurrentContext();
463 const GLuint cmdlen = %u;
465 emit_header(gc->pc, rop, cmdlen);
466 (void) memcpy((void *)(gc->pc + 4), ptr, %u);
468 if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }
470 """ % (n
, size
+ 4, size
)
474 def common_emit_one_arg(self
, p
, pc
, adjust
, extra_offset
):
478 src_ptr
= "&" + p
.name
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() )
487 print '(void) memcpy((void *)(%s + %u + %s), (void *)(%s), %s);' \
488 % (pc
, p
.offset
+ adjust
, extra_offset
, src_ptr
, p
.size_string() )
490 def common_emit_args(self
, f
, pc
, adjust
, skip_vla
):
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
)
497 if p
.is_variable_length():
498 temp
= p
.size_string()
500 extra_offset
+= " + %s" % (temp
)
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."""
519 for param
in f
.parameterIterateGlxSend():
520 if not param
.is_image():
521 self
.common_emit_one_arg(param
, pc
, adjust
, None)
523 if f
.pad_after(param
):
524 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
+ param
.size()) + adjust
)
527 [dim
, width
, height
, depth
, extent
] = param
.get_dimensions()
534 print '(void) memset((void *)(%s + %u), 0, %s);' \
535 % (pc
, (param
.offset
- 4) + adjust
, param
.size_string() )
537 if param
.img_null_flag
:
539 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
- 4) + adjust
)
541 print '(void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (pc
, (param
.offset
- 4) + adjust
, param
.name
)
544 pixHeaderPtr
= "%s + %u" % (pc
, adjust
)
545 pcPtr
= "%s + %u" % (pc
, param
.offset
+ adjust
)
548 if param
.img_send_null
:
549 condition
= '(compsize > 0) && (%s != NULL)' % (param
.name
)
551 condition
= 'compsize > 0'
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
)
556 print ' (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (pixHeaderPtr
, dim
, dim
)
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
)
564 def large_emit_begin(self
, f
, op_name
= None):
566 op_name
= f
.opcode_real_name()
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);'
576 def common_func_print_just_start(self
, f
, name
):
577 print ' struct glx_context * const gc = __glXGetCurrentContext();'
579 # The only reason that single and vendor private commands need
580 # a variable called 'dpy' is because 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
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.
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;'
598 print ' Display * const dpy = gc->currentDpy;'
599 skip_condition
= "dpy != NULL"
601 skip_condition
= "gc->currentDpy != NULL"
603 skip_condition
= None
606 if f
.return_type
!= 'void':
607 print ' %s retval = (%s) 0;' % (f
.return_type
, f
.return_type
)
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
:
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':
629 condition_list
.append( skip_condition
)
631 if len( condition_list
) > 0:
632 if len( condition_list
) > 1:
633 skip_condition
= "(%s)" % (string
.join( condition_list
, ") && (" ))
635 skip_condition
= "%s" % (condition_list
.pop(0))
637 print ' if (__builtin_expect(%s, 1)) {' % (skip_condition
)
643 def printSingleFunction(self
, f
, name
):
644 self
.common_func_print_just_start(f
, name
)
647 print ' printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
649 if name
not in f
.glx_vendorpriv_names
:
652 print '#ifdef USE_XCB'
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
)
662 for p
in f
.parameterIterator():
667 if p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP":
668 extra_iparams
.append("state->storePack.swapEndian")
670 extra_iparams
.append("0")
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")
677 iparams
.append(p
.name
)
680 xcb_request
= '%s(%s)' % (xcb_name
, ", ".join(["c", "gc->currentContextTag"] + iparams
+ extra_iparams
))
683 print ' %s_reply_t *reply = %s_reply(c, %s, NULL);' % (xcb_name
, xcb_name
, xcb_request
)
685 if output
.is_image():
686 [dim
, w
, h
, d
, junk
] = output
.get_dimensions()
687 if f
.dimensions_in_reply
:
694 print ' if (%s == 0) { %s = 1; }' % (h
, h
)
698 print ' if (%s == 0) { %s = 1; }' % (d
, d
)
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
)
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())
705 print ' /* the XXX_data_length() xcb function name is misleading, it returns the number */'
706 print ' /* of elements, not the length of the data part. A single element is embedded. */'
707 print ' if (%s_data_length(reply) == 1)' % (xcb_name
)
708 print ' (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output
.name
)
710 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
712 if f
.return_type
!= 'void':
713 print ' retval = reply->ret_val;'
714 print ' free(reply);'
716 print ' ' + xcb_request
+ ';'
718 # End of XCB specific.
721 if f
.parameters
!= []:
722 pc_decl
= "GLubyte const * pc ="
726 if name
in f
.glx_vendorpriv_names
:
727 print ' %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl
, f
.opcode_real_name(), f
.opcode_vendor_name(name
))
729 print ' %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl
, f
.opcode_name())
731 self
.common_emit_args(f
, "pc", 0, 0)
733 images
= f
.get_images()
737 o
= f
.command_fixed_length() - 4
738 print ' *(int32_t *)(pc + %u) = 0;' % (o
)
739 if img
.img_format
!= "GL_COLOR_INDEX" or img
.img_type
!= "GL_BITMAP":
740 print ' * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o
)
743 print ' * (int8_t *)(pc + %u) = %s;' % (o
+ 1, f
.img_reset
)
748 if f
.return_type
!= 'void':
749 return_name
= " retval"
750 return_str
= " retval = (%s)" % (f
.return_type
)
752 return_str
= " (void)"
756 for p
in f
.parameterIterateOutputs():
758 [dim
, w
, h
, d
, junk
] = p
.get_dimensions()
759 if f
.dimensions_in_reply
:
760 print " __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim
, p
.img_format
, p
.img_type
, p
.name
)
762 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
)
766 if f
.reply_always_array
:
771 # gl_parameter.size() returns the size
772 # of the entire data item. If the
773 # item is a fixed-size array, this is
774 # the size of the whole array. This
775 # is not what __glXReadReply wants. It
776 # wants the size of a single data
777 # element in the reply packet.
778 # Dividing by the array size (1 for
779 # non-arrays) gives us this.
781 s
= p
.size() / p
.get_element_count()
782 print " %s __glXReadReply(dpy, %s, %s, %s);" % (return_str
, s
, p
.name
, aa
)
786 # If a reply wasn't read to fill an output parameter,
787 # read a NULL reply to get the return value.
790 print " %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str
)
794 # Only emit the extra glFinish call for functions
795 # that don't already require a reply from the server.
796 print ' __indirect_glFinish();'
799 print ' printf( "Exit %%s.\\n", "gl%s" );' % (name
)
802 print ' UnlockDisplay(dpy); SyncHandle();'
804 if name
not in f
.glx_vendorpriv_names
:
805 print '#endif /* USE_XCB */'
808 print ' return%s;' % (return_name
)
812 def printPixelFunction(self
, f
):
813 if self
.pixel_stubs
.has_key( f
.name
):
814 # Normally gl_function::get_parameter_string could be
815 # used. However, this call needs to have the missing
816 # dimensions (e.g., a fake height value for
817 # glTexImage1D) added in.
820 for param
in f
.parameterIterateGlxSend():
824 p_string
+= ", " + param
.name
827 [dim
, junk
, junk
, junk
, junk
] = param
.get_dimensions()
829 if f
.pad_after(param
):
832 print ' %s(%s, %u%s );' % (self
.pixel_stubs
[f
.name
] , f
.opcode_name(), dim
, p_string
)
836 if self
.common_func_print_just_start(f
, None):
843 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
844 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
845 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
851 opcode
= f
.opcode_real_name()
853 print 'emit_header(gc->pc, %s, cmdlen);' % (opcode
)
855 self
.pixel_emit_args( f
, "gc->pc", 0 )
856 print 'gc->pc += cmdlen;'
857 print 'if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
863 self
.large_emit_begin(f
, opcode
)
864 self
.pixel_emit_args(f
, "pc", 1)
868 if trailer
: print trailer
872 def printRenderFunction(self
, f
):
873 # There is a class of GL functions that take a single pointer
874 # as a parameter. This pointer points to a fixed-size chunk
875 # of data, and the protocol for this functions is very
876 # regular. Since they are so regular and there are so many
877 # of them, special case them with generic functions. On
878 # x86, this saves about 26KB in the libGL.so binary.
880 if f
.variable_length_parameter() == None and len(f
.parameters
) == 1:
883 cmdlen
= f
.command_fixed_length()
884 if cmdlen
in self
.generic_sizes
:
885 print ' generic_%u_byte( %s, %s );' % (cmdlen
, f
.opcode_real_name(), p
.name
)
888 if self
.common_func_print_just_start(f
, None):
894 print 'printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
897 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
898 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
899 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
902 print 'emit_header(gc->pc, %s, cmdlen);' % (f
.opcode_real_name())
904 self
.common_emit_args(f
, "gc->pc", 4, 0)
905 print 'gc->pc += cmdlen;'
906 print 'if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
912 self
.large_emit_begin(f
)
913 self
.common_emit_args(f
, "pc", 8, 1)
915 p
= f
.variable_length_parameter()
916 print ' __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (p
.offset
+ 8, p
.name
, p
.size_string())
920 print '__indirect_glFinish();'
921 print 'printf( "Exit %%s.\\n", "gl%s" );' % (f
.name
)
923 if trailer
: print trailer
927 class PrintGlxProtoInit_c(gl_XML
.gl_print_base
):
929 gl_XML
.gl_print_base
.__init
__(self
)
931 self
.name
= "glX_proto_send.py (from Mesa)"
932 self
.license
= license
.bsd_license_template
% ( \
933 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
934 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
938 def printRealHeader(self
):
940 * \\file indirect_init.c
941 * Initialize indirect rendering dispatch table.
943 * \\author Kevin E. Martin <kevin@precisioninsight.com>
944 * \\author Brian Paul <brian@precisioninsight.com>
945 * \\author Ian Romanick <idr@us.ibm.com>
948 #include "indirect_init.h"
949 #include "indirect.h"
953 #ifndef GLX_USE_APPLEGL
956 * No-op function used to initialize functions that have no GLX protocol
959 static int NoOp(void)
965 * Create and initialize a new GL dispatch table. The table is initialized
966 * with GLX indirect rendering protocol functions.
968 struct _glapi_table * __glXNewIndirectAPI( void )
975 entries = _glapi_get_dispatch_table_size();
976 table = malloc(entries * sizeof(_glapi_proc));
980 /* first, set all entries to point to no-op functions */
981 for (i = 0; i < entries; i++) {
982 table[i] = (_glapi_proc) NoOp;
985 /* now, initialize the entries we understand */"""
987 def printRealFooter(self
):
989 return (struct _glapi_table *) table;
997 def printBody(self
, api
):
998 for [name
, number
] in api
.categoryIterate():
1000 preamble
= '\n /* %3u. %s */\n' % (int(number
), name
)
1002 preamble
= '\n /* %s */\n' % (name
)
1004 for func
in api
.functionIterateByCategory(name
):
1005 if func
.client_supported_for_indirect():
1011 print ' table[{offset}] = (_glapi_proc) __indirect_gl{name};'.format(name
= func
.name
, offset
= func
.offset
)
1013 print ' o = _glapi_get_proc_offset("gl{0}");'.format(func
.name
)
1014 print ' assert(o > 0);'
1015 print ' table[o] = (_glapi_proc) __indirect_gl{0};'.format(func
.name
)
1020 class PrintGlxProtoInit_h(gl_XML
.gl_print_base
):
1022 gl_XML
.gl_print_base
.__init
__(self
)
1024 self
.name
= "glX_proto_send.py (from Mesa)"
1025 self
.license
= license
.bsd_license_template
% ( \
1026 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
1027 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
1028 self
.header_tag
= "_INDIRECT_H_"
1030 self
.last_category
= ""
1034 def printRealHeader(self
):
1037 * Prototypes for indirect rendering functions.
1039 * \\author Kevin E. Martin <kevin@precisioninsight.com>
1040 * \\author Ian Romanick <idr@us.ibm.com>
1043 self
.printFastcall()
1044 self
.printNoinline()
1047 #include <X11/Xfuncproto.h>
1048 #include "glxclient.h"
1050 extern _X_HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
1051 void * dest, GLboolean reply_is_always_array );
1053 extern _X_HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
1054 struct glx_context * gc, unsigned max_dim, GLint width, GLint height,
1055 GLint depth, GLenum format, GLenum type, void * dest,
1056 GLboolean dimensions_in_reply );
1058 extern _X_HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
1059 struct glx_context * gc, GLint sop, GLint cmdlen );
1061 extern _X_HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
1062 struct glx_context * gc, GLint code, GLint vop, GLint cmdlen );
1066 def printBody(self
, api
):
1067 for func
in api
.functionIterateGlx():
1068 params
= func
.get_parameter_string()
1070 print 'extern _X_HIDDEN %s __indirect_gl%s(%s);' % (func
.return_type
, func
.name
, params
)
1072 for n
in func
.entry_points
:
1073 if func
.has_different_protocol(n
):
1074 asdf
= func
.static_glx_name(n
)
1075 if asdf
not in func
.static_entry_points
:
1076 print 'extern _X_HIDDEN %s gl%s(%s);' % (func
.return_type
, asdf
, params
)
1077 # give it a easy-to-remember name
1078 if func
.client_handcode
:
1079 print '#define gl_dispatch_stub_%s gl%s' % (n
, asdf
)
1081 print 'GLAPI %s GLAPIENTRY gl%s(%s);' % (func
.return_type
, asdf
, params
)
1086 print '#ifdef GLX_SHARED_GLAPI'
1087 print 'extern _X_HIDDEN void (*__indirect_get_proc_address(const char *name))(void);'
1092 """Parse input and returned a parsed namespace."""
1093 parser
= argparse
.ArgumentParser()
1094 parser
.add_argument('-f',
1095 default
='gl_API.xml',
1097 help='An XML file describing an API')
1098 parser
.add_argument('-m',
1101 choices
=frozenset(['proto', 'init_c', 'init_h']),
1102 help='which file to generate')
1103 parser
.add_argument('-d',
1104 action
='store_true',
1106 help='turn debug mode on.')
1107 return parser
.parse_args()
1111 """Main function."""
1114 if args
.mode
== "proto":
1115 printer
= PrintGlxProtoStubs()
1116 elif args
.mode
== "init_c":
1117 printer
= PrintGlxProtoInit_c()
1118 elif args
.mode
== "init_h":
1119 printer
= PrintGlxProtoInit_h()
1121 printer
.debug
= args
.debug
1122 api
= gl_XML
.parse_GL_API(args
.filename
, glX_XML
.glx_item_factory())
1124 printer
.Print( api
)
1127 if __name__
== '__main__':