d458214fb74b3c7cf0f9176309d342fc61a16eb2
2 # (C) Copyright IBM Corporation 2004, 2005
4 # Copyright (c) 2015 Intel Corporation
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:
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
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
26 # Ian Romanick <idr@us.ibm.com>
27 # Jeremy Kolb <jkolb@brandeis.edu>
31 import gl_XML
, glX_XML
, glX_proto_common
, license
34 def convertStringForXCB(str):
39 if str[i
:i
+3] in special
:
40 tmp
= '%s_%s' % (tmp
, string
.lower(str[i
:i
+3]))
42 elif str[i
].isupper():
43 tmp
= '%s_%s' % (tmp
, string
.lower(str[i
]))
45 tmp
= '%s%s' % (tmp
, str[i
])
49 def hash_pixel_function(func
):
50 """Generate a 'unique' key for a pixel function. The key is based on
51 the parameters written in the command packet. This includes any
52 padding that might be added for the original function and the 'NULL
59 for param
in func
.parameterIterateGlxSend():
61 [dim
, junk
, junk
, junk
, junk
] = param
.get_dimensions()
64 hash_pre
= "%uD%uD_" % (d
- 1, d
)
66 if param
.img_null_flag
:
69 h
+= "%u" % (param
.size())
71 if func
.pad_after(param
):
75 n
= func
.name
.replace("%uD" % (dim
), "")
76 n
= "__glx_%s_%uD%uD" % (n
, d
- 1, d
)
78 h
= hash_pre
+ h
+ hash_suf
82 class glx_pixel_function_stub(glX_XML
.glx_function
):
83 """Dummy class used to generate pixel "utility" functions that are
84 shared by multiple dimension image functions. For example, these
85 objects are used to generate shared functions used to send GLX
86 protocol for TexImage1D and TexImage2D, TexSubImage1D and
87 TexSubImage2D, etc."""
89 def __init__(self
, func
, name
):
90 # The parameters to the utility function are the same as the
91 # parameters to the real function except for the added "pad"
97 self
.parameters_by_name
= {}
98 for _p
in func
.parameterIterator():
100 self
.parameters
.append(p
)
101 self
.parameters_by_name
[ p
.name
] = p
105 self
.images
.append(p
)
108 if p
.img_yoff
== None:
109 p
.img_yoff
= "yoffset"
115 if p
.img_woff
== None:
116 p
.img_woff
= "woffset"
119 pad_name
= func
.pad_after(p
)
123 self
.parameters
.append(pad
)
124 self
.parameters_by_name
[ pad
.name
] = pad
127 self
.return_type
= func
.return_type
131 self
.glx_vendorpriv
= 0
133 self
.glx_doubles_in_order
= func
.glx_doubles_in_order
135 self
.vectorequiv
= None
137 self
.can_be_large
= func
.can_be_large
138 self
.reply_always_array
= func
.reply_always_array
139 self
.dimensions_in_reply
= func
.dimensions_in_reply
140 self
.img_reset
= None
142 self
.server_handcode
= 0
143 self
.client_handcode
= 0
146 self
.count_parameter_list
= func
.count_parameter_list
147 self
.counter_list
= func
.counter_list
148 self
.offsets_calculated
= 0
152 class PrintGlxProtoStubs(glX_proto_common
.glx_print_proto
):
154 glX_proto_common
.glx_print_proto
.__init
__(self
)
155 self
.name
= "glX_proto_send.py (from Mesa)"
156 self
.license
= license
.bsd_license_template
% ( "(C) Copyright IBM Corporation 2004, 2005", "IBM")
159 self
.last_category
= ""
160 self
.generic_sizes
= [3, 4, 6, 8, 12, 16, 24, 32]
161 self
.pixel_stubs
= {}
165 def printRealHeader(self
):
167 print '#include <GL/gl.h>'
168 print '#include "indirect.h"'
169 print '#include "glxclient.h"'
170 print '#include "indirect_size.h"'
171 print '#include "glapi.h"'
172 print '#include <GL/glxproto.h>'
173 print '#include <X11/Xlib-xcb.h>'
174 print '#include <xcb/xcb.h>'
175 print '#include <xcb/glx.h>'
176 print '#include <limits.h>'
183 print 'static _X_INLINE int safe_add(int a, int b)'
185 print ' if (a < 0 || b < 0) return -1;'
186 print ' if (INT_MAX - a < b) return -1;'
187 print ' return a + b;'
189 print 'static _X_INLINE int safe_mul(int a, int b)'
191 print ' if (a < 0 || b < 0) return -1;'
192 print ' if (a == 0 || b == 0) return 0;'
193 print ' if (a > INT_MAX / b) return -1;'
194 print ' return a * b;'
196 print 'static _X_INLINE int safe_pad(int a)'
199 print ' if (a < 0) return -1;'
200 print ' if ((ret = safe_add(a, 3)) < 0) return -1;'
201 print ' return ret & (GLuint)~3;'
205 print '#ifndef __GNUC__'
206 print '# define __builtin_expect(x, y) x'
209 print '/* If the size and opcode values are known at compile-time, this will, on'
210 print ' * x86 at least, emit them with a single instruction.'
212 print '#define emit_header(dest, op, size) \\'
213 print ' do { union { short s[2]; int i; } temp; \\'
214 print ' temp.s[0] = (size); temp.s[1] = (op); \\'
215 print ' *((int *)(dest)) = temp.i; } while(0)'
217 print """NOINLINE CARD32
218 __glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array )
220 xGLXSingleReply reply;
222 (void) _XReply(dpy, (xReply *) & reply, 0, False);
224 if ((reply.length > 0) || reply_is_always_array) {
225 const GLint bytes = (reply_is_always_array)
226 ? (4 * reply.length) : (reply.size * size);
227 const GLint extra = 4 - (bytes & 3);
229 _XRead(dpy, dest, bytes);
231 _XEatData(dpy, extra);
235 (void) memcpy( dest, &(reply.pad3), size);
243 __glXReadPixelReply( Display *dpy, struct glx_context * gc, unsigned max_dim,
244 GLint width, GLint height, GLint depth, GLenum format, GLenum type,
245 void * dest, GLboolean dimensions_in_reply )
247 xGLXSingleReply reply;
250 (void) _XReply(dpy, (xReply *) & reply, 0, False);
252 if ( dimensions_in_reply ) {
257 if ((height == 0) || (max_dim < 2)) { height = 1; }
258 if ((depth == 0) || (max_dim < 3)) { depth = 1; }
261 size = reply.length * 4;
263 void * buf = malloc( size );
266 _XEatData(dpy, size);
267 __glXSetError(gc, GL_OUT_OF_MEMORY);
270 const GLint extra = 4 - (size & 3);
272 _XRead(dpy, buf, size);
274 _XEatData(dpy, extra);
277 __glEmptyImage(gc, 3, width, height, depth, format, type,
284 #define X_GLXSingle 0
286 NOINLINE FASTCALL GLubyte *
287 __glXSetupSingleRequest( struct glx_context * gc, GLint sop, GLint cmdlen )
290 Display * const dpy = gc->currentDpy;
292 (void) __glXFlushRenderBuffer(gc, gc->pc);
294 GetReqExtra(GLXSingle, cmdlen, req);
295 req->reqType = gc->majorOpcode;
296 req->contextTag = gc->currentContextTag;
298 return (GLubyte *)(req) + sz_xGLXSingleReq;
301 NOINLINE FASTCALL GLubyte *
302 __glXSetupVendorRequest( struct glx_context * gc, GLint code, GLint vop, GLint cmdlen )
304 xGLXVendorPrivateReq * req;
305 Display * const dpy = gc->currentDpy;
307 (void) __glXFlushRenderBuffer(gc, gc->pc);
309 GetReqExtra(GLXVendorPrivate, cmdlen, req);
310 req->reqType = gc->majorOpcode;
312 req->vendorCode = vop;
313 req->contextTag = gc->currentContextTag;
314 return (GLubyte *)(req) + sz_xGLXVendorPrivateReq;
317 const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 };
319 #define zero (__glXDefaultPixelStore+0)
320 #define one (__glXDefaultPixelStore+8)
321 #define default_pixel_store_1D (__glXDefaultPixelStore+4)
322 #define default_pixel_store_1D_size 20
323 #define default_pixel_store_2D (__glXDefaultPixelStore+4)
324 #define default_pixel_store_2D_size 20
325 #define default_pixel_store_3D (__glXDefaultPixelStore+0)
326 #define default_pixel_store_3D_size 36
327 #define default_pixel_store_4D (__glXDefaultPixelStore+0)
328 #define default_pixel_store_4D_size 36
331 for size
in self
.generic_sizes
:
332 self
.print_generic_function(size
)
336 def printBody(self
, api
):
338 self
.pixel_stubs
= {}
341 for func
in api
.functionIterateGlx():
342 if func
.client_handcode
: continue
344 # If the function is a pixel function with a certain
345 # GLX protocol signature, create a fake stub function
346 # for it. For example, create a single stub function
347 # that is used to implement both glTexImage1D and
350 if func
.glx_rop
!= 0:
352 for image
in func
.get_images():
353 if image
.img_pad_dimensions
:
359 [h
, n
] = hash_pixel_function(func
)
362 self
.pixel_stubs
[ func
.name
] = n
363 if h
not in generated_stubs
:
364 generated_stubs
.append(h
)
366 fake_func
= glx_pixel_function_stub( func
, n
)
367 self
.printFunction(fake_func
, fake_func
.name
)
370 self
.printFunction(func
, func
.name
)
371 if func
.glx_sop
and func
.glx_vendorpriv
:
372 self
.printFunction(func
, func
.glx_vendorpriv_names
[0])
374 self
.printGetProcAddress(api
)
377 def printGetProcAddress(self
, api
):
379 for func
in api
.functionIterateGlx():
380 for n
in func
.entry_points
:
381 if func
.has_different_protocol(n
):
382 procs
[n
] = func
.static_glx_name(n
)
385 #ifdef GLX_INDIRECT_RENDERING
387 static const struct proc_pair
391 } proc_pairs[%d] = {""" % len(procs
)
394 for i
in xrange(len(names
)):
395 comma
= ',' if i
< len(names
) - 1 else ''
396 print ' { "%s", (_glapi_proc) gl%s }%s' % (names
[i
], procs
[names
[i
]], comma
)
400 __indirect_get_proc_compare(const void *key, const void *memb)
402 const struct proc_pair *pair = (const struct proc_pair *) memb;
403 return strcmp((const char *) key, pair->name);
407 __indirect_get_proc_address(const char *name)
409 const struct proc_pair *pair;
414 pair = (const struct proc_pair *) bsearch((const void *) name,
415 (const void *) proc_pairs, ARRAY_SIZE(proc_pairs), sizeof(proc_pairs[0]),
416 __indirect_get_proc_compare);
418 return (pair) ? pair->proc : NULL;
421 #endif /* GLX_INDIRECT_RENDERING */
426 def printFunction(self
, func
, name
):
428 if func
.glx_rop
== ~
0:
429 print 'static %s' % (func
.return_type
)
430 print '%s( unsigned opcode, unsigned dim, %s )' % (func
.name
, func
.get_parameter_string())
433 if func
.has_different_protocol(name
):
434 if func
.return_type
== "void":
437 ret_string
= "return "
439 func_name
= func
.static_glx_name(name
)
440 print '#define %s %d' % (func
.opcode_vendor_name(name
), func
.glx_vendorpriv
)
441 print '%s gl%s(%s)' % (func
.return_type
, func_name
, func
.get_parameter_string())
443 print ' struct glx_context * const gc = __glXGetCurrentContext();'
445 print '#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)'
446 print ' if (gc->isDirect) {'
447 print ' const _glapi_proc *const disp_table = (_glapi_proc *)GET_DISPATCH();'
448 print ' PFNGL%sPROC p =' % (name
.upper())
449 print ' (PFNGL%sPROC) disp_table[%d];' % (name
.upper(), func
.offset
)
450 print ' %sp(%s);' % (ret_string
, func
.get_called_parameter_string())
457 print '#define %s %d' % (func
.opcode_name(), func
.opcode_value())
459 print '%s __indirect_gl%s(%s)' % (func
.return_type
, name
, func
.get_parameter_string())
463 if func
.glx_rop
!= 0 or func
.vectorequiv
!= None:
465 self
.printPixelFunction(func
)
467 self
.printRenderFunction(func
)
468 elif func
.glx_sop
!= 0 or func
.glx_vendorpriv
!= 0:
469 self
.printSingleFunction(func
, name
)
472 print "/* Missing GLX protocol for %s. */" % (name
)
478 def print_generic_function(self
, n
):
480 print """static FASTCALL NOINLINE void
481 generic_%u_byte( GLint rop, const void * ptr )
483 struct glx_context * const gc = __glXGetCurrentContext();
484 const GLuint cmdlen = %u;
486 emit_header(gc->pc, rop, cmdlen);
487 (void) memcpy((void *)(gc->pc + 4), ptr, %u);
489 if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }
491 """ % (n
, size
+ 4, size
)
495 def common_emit_one_arg(self
, p
, pc
, adjust
, extra_offset
):
499 src_ptr
= "&" + p
.name
502 print '(void) memset((void *)(%s + %u), 0, %s);' \
503 % (pc
, p
.offset
+ adjust
, p
.size_string() )
504 elif not extra_offset
:
505 print '(void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
506 % (pc
, p
.offset
+ adjust
, src_ptr
, p
.size_string() )
508 print '(void) memcpy((void *)(%s + %u + %s), (void *)(%s), %s);' \
509 % (pc
, p
.offset
+ adjust
, extra_offset
, src_ptr
, p
.size_string() )
511 def common_emit_args(self
, f
, pc
, adjust
, skip_vla
):
514 for p
in f
.parameterIterateGlxSend( not skip_vla
):
515 if p
.name
!= f
.img_reset
:
516 self
.common_emit_one_arg(p
, pc
, adjust
, extra_offset
)
518 if p
.is_variable_length():
519 temp
= p
.size_string()
521 extra_offset
+= " + %s" % (temp
)
528 def pixel_emit_args(self
, f
, pc
, large
):
529 """Emit the arguments for a pixel function. This differs from
530 common_emit_args in that pixel functions may require padding
531 be inserted (i.e., for the missing width field for
532 TexImage1D), and they may also require a 'NULL image' flag
533 be inserted before the image data."""
540 for param
in f
.parameterIterateGlxSend():
541 if not param
.is_image():
542 self
.common_emit_one_arg(param
, pc
, adjust
, None)
544 if f
.pad_after(param
):
545 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
+ param
.size()) + adjust
)
548 [dim
, width
, height
, depth
, extent
] = param
.get_dimensions()
555 print '(void) memset((void *)(%s + %u), 0, %s);' \
556 % (pc
, (param
.offset
- 4) + adjust
, param
.size_string() )
558 if param
.img_null_flag
:
560 print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
- 4) + adjust
)
562 print '(void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (pc
, (param
.offset
- 4) + adjust
, param
.name
)
565 pixHeaderPtr
= "%s + %u" % (pc
, adjust
)
566 pcPtr
= "%s + %u" % (pc
, param
.offset
+ adjust
)
569 if param
.img_send_null
:
570 condition
= '(compsize > 0) && (%s != NULL)' % (param
.name
)
572 condition
= 'compsize > 0'
574 print 'if (%s) {' % (condition
)
575 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
)
577 print ' (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (pixHeaderPtr
, dim
, dim
)
580 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
)
585 def large_emit_begin(self
, f
, op_name
= None):
587 op_name
= f
.opcode_real_name()
589 print 'const GLint op = %s;' % (op_name
)
590 print 'const GLuint cmdlenLarge = cmdlen + 4;'
591 print 'GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);'
592 print '(void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);'
593 print '(void) memcpy((void *)(pc + 4), (void *)(&op), 4);'
597 def common_func_print_just_start(self
, f
, name
):
598 print ' struct glx_context * const gc = __glXGetCurrentContext();'
600 # The only reason that single and vendor private commands need
601 # a variable called 'dpy' is because they use the SyncHandle
602 # macro. For whatever brain-dead reason, that macro is hard-
603 # coded to use a variable called 'dpy' instead of taking a
606 # FIXME Simplify the logic related to skip_condition and
607 # FIXME condition_list in this function. Basically, remove
608 # FIXME skip_condition, and just append the "dpy != NULL" type
609 # FIXME condition to condition_list from the start. The only
610 # FIXME reason it's done in this confusing way now is to
611 # FIXME minimize the diffs in the generated code.
614 for p
in f
.parameterIterateOutputs():
615 if p
.is_image() and (p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP"):
616 print ' const __GLXattribute * const state = gc->client_state_private;'
619 print ' Display * const dpy = gc->currentDpy;'
620 skip_condition
= "dpy != NULL"
622 skip_condition
= "gc->currentDpy != NULL"
624 skip_condition
= None
627 if f
.return_type
!= 'void':
628 print ' %s retval = (%s) 0;' % (f
.return_type
, f
.return_type
)
631 if name
!= None and name
not in f
.glx_vendorpriv_names
:
632 print '#ifndef USE_XCB'
633 self
.emit_packet_size_calculation(f
, 0)
634 if name
!= None and name
not in f
.glx_vendorpriv_names
:
637 if f
.command_variable_length() != "":
638 print " if (0%s < 0) {" % f
.command_variable_length()
639 print " __glXSetError(gc, GL_INVALID_VALUE);"
640 if f
.return_type
!= 'void':
647 for p
in f
.parameterIterateCounters():
648 condition_list
.append( "%s >= 0" % (p
.name
) )
649 # 'counter' parameters cannot be negative
650 print " if (%s < 0) {" % p
.name
651 print " __glXSetError(gc, GL_INVALID_VALUE);"
652 if f
.return_type
!= 'void':
659 condition_list
.append( skip_condition
)
661 if len( condition_list
) > 0:
662 if len( condition_list
) > 1:
663 skip_condition
= "(%s)" % (string
.join( condition_list
, ") && (" ))
665 skip_condition
= "%s" % (condition_list
.pop(0))
667 print ' if (__builtin_expect(%s, 1)) {' % (skip_condition
)
673 def printSingleFunction(self
, f
, name
):
674 self
.common_func_print_just_start(f
, name
)
677 print ' printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
679 if name
not in f
.glx_vendorpriv_names
:
682 print '#ifdef USE_XCB'
684 print ' printf("\\tUsing XCB.\\n");'
685 print ' xcb_connection_t *c = XGetXCBConnection(dpy);'
686 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
687 xcb_name
= 'xcb_glx%s' % convertStringForXCB(name
)
692 for p
in f
.parameterIterator():
697 if p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP":
698 extra_iparams
.append("state->storePack.swapEndian")
700 extra_iparams
.append("0")
702 # Hardcode this in. lsb_first param (apparently always GL_FALSE)
703 # also present in GetPolygonStipple, but taken care of above.
704 if xcb_name
== "xcb_glx_read_pixels":
705 extra_iparams
.append("0")
707 iparams
.append(p
.name
)
710 xcb_request
= '%s(%s)' % (xcb_name
, ", ".join(["c", "gc->currentContextTag"] + iparams
+ extra_iparams
))
713 print ' %s_reply_t *reply = %s_reply(c, %s, NULL);' % (xcb_name
, xcb_name
, xcb_request
)
715 if output
.is_image():
716 [dim
, w
, h
, d
, junk
] = output
.get_dimensions()
717 if f
.dimensions_in_reply
:
724 print ' if (%s == 0) { %s = 1; }' % (h
, h
)
728 print ' if (%s == 0) { %s = 1; }' % (d
, d
)
730 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
)
732 if f
.reply_always_array
:
733 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
735 print ' /* the XXX_data_length() xcb function name is misleading, it returns the number */'
736 print ' /* of elements, not the length of the data part. A single element is embedded. */'
737 print ' if (%s_data_length(reply) == 1)' % (xcb_name
)
738 print ' (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output
.name
)
740 print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string())
742 if f
.return_type
!= 'void':
743 print ' retval = reply->ret_val;'
744 print ' free(reply);'
746 print ' ' + xcb_request
+ ';'
748 # End of XCB specific.
751 if f
.parameters
!= []:
752 pc_decl
= "GLubyte const * pc ="
756 if name
in f
.glx_vendorpriv_names
:
757 print ' %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl
, f
.opcode_real_name(), f
.opcode_vendor_name(name
))
759 print ' %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl
, f
.opcode_name())
761 self
.common_emit_args(f
, "pc", 0, 0)
763 images
= f
.get_images()
767 o
= f
.command_fixed_length() - 4
768 print ' *(int32_t *)(pc + %u) = 0;' % (o
)
769 if img
.img_format
!= "GL_COLOR_INDEX" or img
.img_type
!= "GL_BITMAP":
770 print ' * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o
)
773 print ' * (int8_t *)(pc + %u) = %s;' % (o
+ 1, f
.img_reset
)
778 if f
.return_type
!= 'void':
779 return_name
= " retval"
780 return_str
= " retval = (%s)" % (f
.return_type
)
782 return_str
= " (void)"
786 for p
in f
.parameterIterateOutputs():
788 [dim
, w
, h
, d
, junk
] = p
.get_dimensions()
789 if f
.dimensions_in_reply
:
790 print " __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim
, p
.img_format
, p
.img_type
, p
.name
)
792 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
)
796 if f
.reply_always_array
:
801 # gl_parameter.size() returns the size
802 # of the entire data item. If the
803 # item is a fixed-size array, this is
804 # the size of the whole array. This
805 # is not what __glXReadReply wants. It
806 # wants the size of a single data
807 # element in the reply packet.
808 # Dividing by the array size (1 for
809 # non-arrays) gives us this.
811 s
= p
.size() / p
.get_element_count()
812 print " %s __glXReadReply(dpy, %s, %s, %s);" % (return_str
, s
, p
.name
, aa
)
816 # If a reply wasn't read to fill an output parameter,
817 # read a NULL reply to get the return value.
820 print " %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str
)
824 # Only emit the extra glFinish call for functions
825 # that don't already require a reply from the server.
826 print ' __indirect_glFinish();'
829 print ' printf( "Exit %%s.\\n", "gl%s" );' % (name
)
832 print ' UnlockDisplay(dpy); SyncHandle();'
834 if name
not in f
.glx_vendorpriv_names
:
835 print '#endif /* USE_XCB */'
838 print ' return%s;' % (return_name
)
842 def printPixelFunction(self
, f
):
843 if self
.pixel_stubs
.has_key( f
.name
):
844 # Normally gl_function::get_parameter_string could be
845 # used. However, this call needs to have the missing
846 # dimensions (e.g., a fake height value for
847 # glTexImage1D) added in.
850 for param
in f
.parameterIterateGlxSend():
854 p_string
+= ", " + param
.name
857 [dim
, junk
, junk
, junk
, junk
] = param
.get_dimensions()
859 if f
.pad_after(param
):
862 print ' %s(%s, %u%s );' % (self
.pixel_stubs
[f
.name
] , f
.opcode_name(), dim
, p_string
)
866 if self
.common_func_print_just_start(f
, None):
873 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
874 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
875 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
881 opcode
= f
.opcode_real_name()
883 print 'emit_header(gc->pc, %s, cmdlen);' % (opcode
)
885 self
.pixel_emit_args( f
, "gc->pc", 0 )
886 print 'gc->pc += cmdlen;'
887 print 'if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
893 self
.large_emit_begin(f
, opcode
)
894 self
.pixel_emit_args(f
, "pc", 1)
898 if trailer
: print trailer
902 def printRenderFunction(self
, f
):
903 # There is a class of GL functions that take a single pointer
904 # as a parameter. This pointer points to a fixed-size chunk
905 # of data, and the protocol for this functions is very
906 # regular. Since they are so regular and there are so many
907 # of them, special case them with generic functions. On
908 # x86, this saves about 26KB in the libGL.so binary.
910 if f
.variable_length_parameter() == None and len(f
.parameters
) == 1:
913 cmdlen
= f
.command_fixed_length()
914 if cmdlen
in self
.generic_sizes
:
915 print ' generic_%u_byte( %s, %s );' % (cmdlen
, f
.opcode_real_name(), p
.name
)
918 if self
.common_func_print_just_start(f
, None):
924 print 'printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
)
927 print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
928 print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
929 print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
932 print 'emit_header(gc->pc, %s, cmdlen);' % (f
.opcode_real_name())
934 self
.common_emit_args(f
, "gc->pc", 4, 0)
935 print 'gc->pc += cmdlen;'
936 print 'if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
942 self
.large_emit_begin(f
)
943 self
.common_emit_args(f
, "pc", 8, 1)
945 p
= f
.variable_length_parameter()
946 print ' __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (p
.offset
+ 8, p
.name
, p
.size_string())
950 print '__indirect_glFinish();'
951 print 'printf( "Exit %%s.\\n", "gl%s" );' % (f
.name
)
953 if trailer
: print trailer
957 class PrintGlxProtoInit_c(gl_XML
.gl_print_base
):
959 gl_XML
.gl_print_base
.__init
__(self
)
961 self
.name
= "glX_proto_send.py (from Mesa)"
962 self
.license
= license
.bsd_license_template
% ( \
963 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
964 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
968 def printRealHeader(self
):
970 * \\file indirect_init.c
971 * Initialize indirect rendering dispatch table.
973 * \\author Kevin E. Martin <kevin@precisioninsight.com>
974 * \\author Brian Paul <brian@precisioninsight.com>
975 * \\author Ian Romanick <idr@us.ibm.com>
978 #include "indirect_init.h"
979 #include "indirect.h"
983 #ifndef GLX_USE_APPLEGL
986 * No-op function used to initialize functions that have no GLX protocol
989 static int NoOp(void)
995 * Create and initialize a new GL dispatch table. The table is initialized
996 * with GLX indirect rendering protocol functions.
998 struct _glapi_table * __glXNewIndirectAPI( void )
1005 entries = _glapi_get_dispatch_table_size();
1006 table = malloc(entries * sizeof(_glapi_proc));
1010 /* first, set all entries to point to no-op functions */
1011 for (i = 0; i < entries; i++) {
1012 table[i] = (_glapi_proc) NoOp;
1015 /* now, initialize the entries we understand */"""
1017 def printRealFooter(self
):
1019 return (struct _glapi_table *) table;
1027 def printBody(self
, api
):
1028 for [name
, number
] in api
.categoryIterate():
1030 preamble
= '\n /* %3u. %s */\n' % (int(number
), name
)
1032 preamble
= '\n /* %s */\n' % (name
)
1034 for func
in api
.functionIterateByCategory(name
):
1035 if func
.client_supported_for_indirect():
1041 print ' table[{offset}] = (_glapi_proc) __indirect_gl{name};'.format(name
= func
.name
, offset
= func
.offset
)
1043 print ' o = _glapi_get_proc_offset("gl{0}");'.format(func
.name
)
1044 print ' assert(o > 0);'
1045 print ' table[o] = (_glapi_proc) __indirect_gl{0};'.format(func
.name
)
1050 class PrintGlxProtoInit_h(gl_XML
.gl_print_base
):
1052 gl_XML
.gl_print_base
.__init
__(self
)
1054 self
.name
= "glX_proto_send.py (from Mesa)"
1055 self
.license
= license
.bsd_license_template
% ( \
1056 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
1057 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
1058 self
.header_tag
= "_INDIRECT_H_"
1060 self
.last_category
= ""
1064 def printRealHeader(self
):
1067 * Prototypes for indirect rendering functions.
1069 * \\author Kevin E. Martin <kevin@precisioninsight.com>
1070 * \\author Ian Romanick <idr@us.ibm.com>
1073 self
.printFastcall()
1074 self
.printNoinline()
1077 #include <X11/Xfuncproto.h>
1078 #include "glxclient.h"
1080 extern _X_HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
1081 void * dest, GLboolean reply_is_always_array );
1083 extern _X_HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
1084 struct glx_context * gc, unsigned max_dim, GLint width, GLint height,
1085 GLint depth, GLenum format, GLenum type, void * dest,
1086 GLboolean dimensions_in_reply );
1088 extern _X_HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
1089 struct glx_context * gc, GLint sop, GLint cmdlen );
1091 extern _X_HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
1092 struct glx_context * gc, GLint code, GLint vop, GLint cmdlen );
1096 def printBody(self
, api
):
1097 for func
in api
.functionIterateGlx():
1098 params
= func
.get_parameter_string()
1100 print 'extern _X_HIDDEN %s __indirect_gl%s(%s);' % (func
.return_type
, func
.name
, params
)
1102 for n
in func
.entry_points
:
1103 if func
.has_different_protocol(n
):
1104 asdf
= func
.static_glx_name(n
)
1105 if asdf
not in func
.static_entry_points
:
1106 print 'extern _X_HIDDEN %s gl%s(%s);' % (func
.return_type
, asdf
, params
)
1107 # give it a easy-to-remember name
1108 if func
.client_handcode
:
1109 print '#define gl_dispatch_stub_%s gl%s' % (n
, asdf
)
1111 print 'GLAPI %s GLAPIENTRY gl%s(%s);' % (func
.return_type
, asdf
, params
)
1116 print '#ifdef GLX_INDIRECT_RENDERING'
1117 print 'extern _X_HIDDEN void (*__indirect_get_proc_address(const char *name))(void);'
1122 """Parse input and returned a parsed namespace."""
1123 parser
= argparse
.ArgumentParser()
1124 parser
.add_argument('-f',
1125 default
='gl_API.xml',
1127 help='An XML file describing an API')
1128 parser
.add_argument('-m',
1131 choices
=frozenset(['proto', 'init_c', 'init_h']),
1132 help='which file to generate')
1133 parser
.add_argument('-d',
1134 action
='store_true',
1136 help='turn debug mode on.')
1137 return parser
.parse_args()
1141 """Main function."""
1144 if args
.mode
== "proto":
1145 printer
= PrintGlxProtoStubs()
1146 elif args
.mode
== "init_c":
1147 printer
= PrintGlxProtoInit_c()
1148 elif args
.mode
== "init_h":
1149 printer
= PrintGlxProtoInit_h()
1151 printer
.debug
= args
.debug
1152 api
= gl_XML
.parse_GL_API(args
.filename
, glX_XML
.glx_item_factory())
1154 printer
.Print( api
)
1157 if __name__
== '__main__':