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>
29 from __future__
import print_function
33 import gl_XML
, glX_XML
, glX_proto_common
, license
36 def convertStringForXCB(str):
41 if str[i
:i
+3] in special
:
42 tmp
= '%s_%s' % (tmp
, string
.lower(str[i
:i
+3]))
44 elif str[i
].isupper():
45 tmp
= '%s_%s' % (tmp
, string
.lower(str[i
]))
47 tmp
= '%s%s' % (tmp
, str[i
])
51 def hash_pixel_function(func
):
52 """Generate a 'unique' key for a pixel function. The key is based on
53 the parameters written in the command packet. This includes any
54 padding that might be added for the original function and the 'NULL
61 for param
in func
.parameterIterateGlxSend():
63 [dim
, junk
, junk
, junk
, junk
] = param
.get_dimensions()
66 hash_pre
= "%uD%uD_" % (d
- 1, d
)
68 if param
.img_null_flag
:
71 h
+= "%u" % (param
.size())
73 if func
.pad_after(param
):
77 n
= func
.name
.replace("%uD" % (dim
), "")
78 n
= "__glx_%s_%uD%uD" % (n
, d
- 1, d
)
80 h
= hash_pre
+ h
+ hash_suf
84 class glx_pixel_function_stub(glX_XML
.glx_function
):
85 """Dummy class used to generate pixel "utility" functions that are
86 shared by multiple dimension image functions. For example, these
87 objects are used to generate shared functions used to send GLX
88 protocol for TexImage1D and TexImage2D, TexSubImage1D and
89 TexSubImage2D, etc."""
91 def __init__(self
, func
, name
):
92 # The parameters to the utility function are the same as the
93 # parameters to the real function except for the added "pad"
99 self
.parameters_by_name
= {}
100 for _p
in func
.parameterIterator():
102 self
.parameters
.append(p
)
103 self
.parameters_by_name
[ p
.name
] = p
107 self
.images
.append(p
)
110 if p
.img_yoff
== None:
111 p
.img_yoff
= "yoffset"
117 if p
.img_woff
== None:
118 p
.img_woff
= "woffset"
121 pad_name
= func
.pad_after(p
)
125 self
.parameters
.append(pad
)
126 self
.parameters_by_name
[ pad
.name
] = pad
129 self
.return_type
= func
.return_type
133 self
.glx_vendorpriv
= 0
135 self
.glx_doubles_in_order
= func
.glx_doubles_in_order
137 self
.vectorequiv
= None
139 self
.can_be_large
= func
.can_be_large
140 self
.reply_always_array
= func
.reply_always_array
141 self
.dimensions_in_reply
= func
.dimensions_in_reply
142 self
.img_reset
= None
144 self
.server_handcode
= 0
145 self
.client_handcode
= 0
148 self
.count_parameter_list
= func
.count_parameter_list
149 self
.counter_list
= func
.counter_list
150 self
.offsets_calculated
= 0
154 class PrintGlxProtoStubs(glX_proto_common
.glx_print_proto
):
156 glX_proto_common
.glx_print_proto
.__init
__(self
)
157 self
.name
= "glX_proto_send.py (from Mesa)"
158 self
.license
= license
.bsd_license_template
% ( "(C) Copyright IBM Corporation 2004, 2005", "IBM")
161 self
.last_category
= ""
162 self
.generic_sizes
= [3, 4, 6, 8, 12, 16, 24, 32]
163 self
.pixel_stubs
= {}
167 def printRealHeader(self
):
169 print('#include <GL/gl.h>')
170 print('#include "indirect.h"')
171 print('#include "glxclient.h"')
172 print('#include "indirect_size.h"')
173 print('#include "glapi.h"')
174 print('#include <GL/glxproto.h>')
175 print('#include <X11/Xlib-xcb.h>')
176 print('#include <xcb/xcb.h>')
177 print('#include <xcb/glx.h>')
178 print('#include <limits.h>')
185 print('static _X_INLINE int safe_add(int a, int b)')
187 print(' if (a < 0 || b < 0) return -1;')
188 print(' if (INT_MAX - a < b) return -1;')
189 print(' return a + b;')
191 print('static _X_INLINE int safe_mul(int a, int b)')
193 print(' if (a < 0 || b < 0) return -1;')
194 print(' if (a == 0 || b == 0) return 0;')
195 print(' if (a > INT_MAX / b) return -1;')
196 print(' return a * b;')
198 print('static _X_INLINE int safe_pad(int a)')
201 print(' if (a < 0) return -1;')
202 print(' if ((ret = safe_add(a, 3)) < 0) return -1;')
203 print(' return ret & (GLuint)~3;')
207 print('#ifndef __GNUC__')
208 print('# define __builtin_expect(x, y) x')
211 print('/* If the size and opcode values are known at compile-time, this will, on')
212 print(' * x86 at least, emit them with a single instruction.')
214 print('#define emit_header(dest, op, size) \\')
215 print(' do { union { short s[2]; int i; } temp; \\')
216 print(' temp.s[0] = (size); temp.s[1] = (op); \\')
217 print(' *((int *)(dest)) = temp.i; } while(0)')
219 print("""NOINLINE CARD32
220 __glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array )
222 xGLXSingleReply reply;
224 (void) _XReply(dpy, (xReply *) & reply, 0, False);
226 if ((reply.length > 0) || reply_is_always_array) {
227 const GLint bytes = (reply_is_always_array)
228 ? (4 * reply.length) : (reply.size * size);
229 const GLint extra = 4 - (bytes & 3);
231 _XRead(dpy, dest, bytes);
233 _XEatData(dpy, extra);
237 (void) memcpy( dest, &(reply.pad3), size);
245 __glXReadPixelReply( Display *dpy, struct glx_context * gc, unsigned max_dim,
246 GLint width, GLint height, GLint depth, GLenum format, GLenum type,
247 void * dest, GLboolean dimensions_in_reply )
249 xGLXSingleReply reply;
252 (void) _XReply(dpy, (xReply *) & reply, 0, False);
254 if ( dimensions_in_reply ) {
259 if ((height == 0) || (max_dim < 2)) { height = 1; }
260 if ((depth == 0) || (max_dim < 3)) { depth = 1; }
263 size = reply.length * 4;
265 void * buf = malloc( size );
268 _XEatData(dpy, size);
269 __glXSetError(gc, GL_OUT_OF_MEMORY);
272 const GLint extra = 4 - (size & 3);
274 _XRead(dpy, buf, size);
276 _XEatData(dpy, extra);
279 __glEmptyImage(gc, 3, width, height, depth, format, type,
286 #define X_GLXSingle 0
288 NOINLINE FASTCALL GLubyte *
289 __glXSetupSingleRequest( struct glx_context * gc, GLint sop, GLint cmdlen )
292 Display * const dpy = gc->currentDpy;
294 (void) __glXFlushRenderBuffer(gc, gc->pc);
296 GetReqExtra(GLXSingle, cmdlen, req);
297 req->reqType = gc->majorOpcode;
298 req->contextTag = gc->currentContextTag;
300 return (GLubyte *)(req) + sz_xGLXSingleReq;
303 NOINLINE FASTCALL GLubyte *
304 __glXSetupVendorRequest( struct glx_context * gc, GLint code, GLint vop, GLint cmdlen )
306 xGLXVendorPrivateReq * req;
307 Display * const dpy = gc->currentDpy;
309 (void) __glXFlushRenderBuffer(gc, gc->pc);
311 GetReqExtra(GLXVendorPrivate, cmdlen, req);
312 req->reqType = gc->majorOpcode;
314 req->vendorCode = vop;
315 req->contextTag = gc->currentContextTag;
316 return (GLubyte *)(req) + sz_xGLXVendorPrivateReq;
319 const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 };
321 #define zero (__glXDefaultPixelStore+0)
322 #define one (__glXDefaultPixelStore+8)
323 #define default_pixel_store_1D (__glXDefaultPixelStore+4)
324 #define default_pixel_store_1D_size 20
325 #define default_pixel_store_2D (__glXDefaultPixelStore+4)
326 #define default_pixel_store_2D_size 20
327 #define default_pixel_store_3D (__glXDefaultPixelStore+0)
328 #define default_pixel_store_3D_size 36
329 #define default_pixel_store_4D (__glXDefaultPixelStore+0)
330 #define default_pixel_store_4D_size 36
333 for size
in self
.generic_sizes
:
334 self
.print_generic_function(size
)
338 def printBody(self
, api
):
340 self
.pixel_stubs
= {}
343 for func
in api
.functionIterateGlx():
344 if func
.client_handcode
: continue
346 # If the function is a pixel function with a certain
347 # GLX protocol signature, create a fake stub function
348 # for it. For example, create a single stub function
349 # that is used to implement both glTexImage1D and
352 if func
.glx_rop
!= 0:
354 for image
in func
.get_images():
355 if image
.img_pad_dimensions
:
361 [h
, n
] = hash_pixel_function(func
)
364 self
.pixel_stubs
[ func
.name
] = n
365 if h
not in generated_stubs
:
366 generated_stubs
.append(h
)
368 fake_func
= glx_pixel_function_stub( func
, n
)
369 self
.printFunction(fake_func
, fake_func
.name
)
372 self
.printFunction(func
, func
.name
)
373 if func
.glx_sop
and func
.glx_vendorpriv
:
374 self
.printFunction(func
, func
.glx_vendorpriv_names
[0])
376 self
.printGetProcAddress(api
)
379 def printGetProcAddress(self
, api
):
381 for func
in api
.functionIterateGlx():
382 for n
in func
.entry_points
:
383 if func
.has_different_protocol(n
):
384 procs
[n
] = func
.static_glx_name(n
)
387 #ifdef GLX_INDIRECT_RENDERING
389 static const struct proc_pair
393 } proc_pairs[%d] = {""" % len(procs
))
396 for i
in xrange(len(names
)):
397 comma
= ',' if i
< len(names
) - 1 else ''
398 print(' { "%s", (_glapi_proc) gl%s }%s' % (names
[i
], procs
[names
[i
]], comma
))
402 __indirect_get_proc_compare(const void *key, const void *memb)
404 const struct proc_pair *pair = (const struct proc_pair *) memb;
405 return strcmp((const char *) key, pair->name);
409 __indirect_get_proc_address(const char *name)
411 const struct proc_pair *pair;
416 pair = (const struct proc_pair *) bsearch((const void *) name,
417 (const void *) proc_pairs, ARRAY_SIZE(proc_pairs), sizeof(proc_pairs[0]),
418 __indirect_get_proc_compare);
420 return (pair) ? pair->proc : NULL;
423 #endif /* GLX_INDIRECT_RENDERING */
428 def printFunction(self
, func
, name
):
430 if func
.glx_rop
== ~
0:
431 print('static %s' % (func
.return_type
))
432 print('%s( unsigned opcode, unsigned dim, %s )' % (func
.name
, func
.get_parameter_string()))
435 if func
.has_different_protocol(name
):
436 if func
.return_type
== "void":
439 ret_string
= "return "
441 func_name
= func
.static_glx_name(name
)
442 print('#define %s %d' % (func
.opcode_vendor_name(name
), func
.glx_vendorpriv
))
443 print('%s gl%s(%s)' % (func
.return_type
, func_name
, func
.get_parameter_string()))
445 print(' struct glx_context * const gc = __glXGetCurrentContext();')
447 print('#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)')
448 print(' if (gc->isDirect) {')
449 print(' const _glapi_proc *const disp_table = (_glapi_proc *)GET_DISPATCH();')
450 print(' PFNGL%sPROC p =' % (name
.upper()))
451 print(' (PFNGL%sPROC) disp_table[%d];' % (name
.upper(), func
.offset
))
452 print(' %sp(%s);' % (ret_string
, func
.get_called_parameter_string()))
459 print('#define %s %d' % (func
.opcode_name(), func
.opcode_value()))
461 print('%s __indirect_gl%s(%s)' % (func
.return_type
, name
, func
.get_parameter_string()))
465 if func
.glx_rop
!= 0 or func
.vectorequiv
!= None:
467 self
.printPixelFunction(func
)
469 self
.printRenderFunction(func
)
470 elif func
.glx_sop
!= 0 or func
.glx_vendorpriv
!= 0:
471 self
.printSingleFunction(func
, name
)
474 print("/* Missing GLX protocol for %s. */" % (name
))
480 def print_generic_function(self
, n
):
482 print("""static FASTCALL NOINLINE void
483 generic_%u_byte( GLint rop, const void * ptr )
485 struct glx_context * const gc = __glXGetCurrentContext();
486 const GLuint cmdlen = %u;
488 emit_header(gc->pc, rop, cmdlen);
489 (void) memcpy((void *)(gc->pc + 4), ptr, %u);
491 if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }
493 """ % (n
, size
+ 4, size
))
497 def common_emit_one_arg(self
, p
, pc
, adjust
, extra_offset
):
501 src_ptr
= "&" + p
.name
504 print('(void) memset((void *)(%s + %u), 0, %s);' \
505 % (pc
, p
.offset
+ adjust
, p
.size_string() ))
506 elif not extra_offset
:
507 print('(void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
508 % (pc
, p
.offset
+ adjust
, src_ptr
, p
.size_string() ))
510 print('(void) memcpy((void *)(%s + %u + %s), (void *)(%s), %s);' \
511 % (pc
, p
.offset
+ adjust
, extra_offset
, src_ptr
, p
.size_string() ))
513 def common_emit_args(self
, f
, pc
, adjust
, skip_vla
):
516 for p
in f
.parameterIterateGlxSend( not skip_vla
):
517 if p
.name
!= f
.img_reset
:
518 self
.common_emit_one_arg(p
, pc
, adjust
, extra_offset
)
520 if p
.is_variable_length():
521 temp
= p
.size_string()
523 extra_offset
+= " + %s" % (temp
)
530 def pixel_emit_args(self
, f
, pc
, large
):
531 """Emit the arguments for a pixel function. This differs from
532 common_emit_args in that pixel functions may require padding
533 be inserted (i.e., for the missing width field for
534 TexImage1D), and they may also require a 'NULL image' flag
535 be inserted before the image data."""
542 for param
in f
.parameterIterateGlxSend():
543 if not param
.is_image():
544 self
.common_emit_one_arg(param
, pc
, adjust
, None)
546 if f
.pad_after(param
):
547 print('(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
+ param
.size()) + adjust
))
550 [dim
, width
, height
, depth
, extent
] = param
.get_dimensions()
557 print('(void) memset((void *)(%s + %u), 0, %s);' \
558 % (pc
, (param
.offset
- 4) + adjust
, param
.size_string() ))
560 if param
.img_null_flag
:
562 print('(void) memcpy((void *)(%s + %u), zero, 4);' % (pc
, (param
.offset
- 4) + adjust
))
564 print('(void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (pc
, (param
.offset
- 4) + adjust
, param
.name
))
567 pixHeaderPtr
= "%s + %u" % (pc
, adjust
)
568 pcPtr
= "%s + %u" % (pc
, param
.offset
+ adjust
)
571 if param
.img_send_null
:
572 condition
= '(compsize > 0) && (%s != NULL)' % (param
.name
)
574 condition
= 'compsize > 0'
576 print('if (%s) {' % (condition
))
577 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
))
579 print(' (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (pixHeaderPtr
, dim
, dim
))
582 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
))
587 def large_emit_begin(self
, f
, op_name
= None):
589 op_name
= f
.opcode_real_name()
591 print('const GLint op = %s;' % (op_name
))
592 print('const GLuint cmdlenLarge = cmdlen + 4;')
593 print('GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);')
594 print('(void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);')
595 print('(void) memcpy((void *)(pc + 4), (void *)(&op), 4);')
599 def common_func_print_just_start(self
, f
, name
):
600 print(' struct glx_context * const gc = __glXGetCurrentContext();')
602 # The only reason that single and vendor private commands need
603 # a variable called 'dpy' is because they use the SyncHandle
604 # macro. For whatever brain-dead reason, that macro is hard-
605 # coded to use a variable called 'dpy' instead of taking a
608 # FIXME Simplify the logic related to skip_condition and
609 # FIXME condition_list in this function. Basically, remove
610 # FIXME skip_condition, and just append the "dpy != NULL" type
611 # FIXME condition to condition_list from the start. The only
612 # FIXME reason it's done in this confusing way now is to
613 # FIXME minimize the diffs in the generated code.
616 for p
in f
.parameterIterateOutputs():
617 if p
.is_image() and (p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP"):
618 print(' const __GLXattribute * const state = gc->client_state_private;')
621 print(' Display * const dpy = gc->currentDpy;')
622 skip_condition
= "dpy != NULL"
624 skip_condition
= "gc->currentDpy != NULL"
626 skip_condition
= None
629 if f
.return_type
!= 'void':
630 print(' %s retval = (%s) 0;' % (f
.return_type
, f
.return_type
))
633 if name
!= None and name
not in f
.glx_vendorpriv_names
:
634 print('#ifndef USE_XCB')
635 self
.emit_packet_size_calculation(f
, 0)
636 if name
!= None and name
not in f
.glx_vendorpriv_names
:
639 if f
.command_variable_length() != "":
640 print(" if (0%s < 0) {" % f
.command_variable_length())
641 print(" __glXSetError(gc, GL_INVALID_VALUE);")
642 if f
.return_type
!= 'void':
649 for p
in f
.parameterIterateCounters():
650 condition_list
.append( "%s >= 0" % (p
.name
) )
651 # 'counter' parameters cannot be negative
652 print(" if (%s < 0) {" % p
.name
)
653 print(" __glXSetError(gc, GL_INVALID_VALUE);")
654 if f
.return_type
!= 'void':
661 condition_list
.append( skip_condition
)
663 if len( condition_list
) > 0:
664 if len( condition_list
) > 1:
665 skip_condition
= "(%s)" % (string
.join( condition_list
, ") && (" ))
667 skip_condition
= "%s" % (condition_list
.pop(0))
669 print(' if (__builtin_expect(%s, 1)) {' % (skip_condition
))
675 def printSingleFunction(self
, f
, name
):
676 self
.common_func_print_just_start(f
, name
)
679 print(' printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
))
681 if name
not in f
.glx_vendorpriv_names
:
684 print('#ifdef USE_XCB')
686 print(' printf("\\tUsing XCB.\\n");')
687 print(' xcb_connection_t *c = XGetXCBConnection(dpy);')
688 print(' (void) __glXFlushRenderBuffer(gc, gc->pc);')
689 xcb_name
= 'xcb_glx%s' % convertStringForXCB(name
)
694 for p
in f
.parameterIterator():
699 if p
.img_format
!= "GL_COLOR_INDEX" or p
.img_type
!= "GL_BITMAP":
700 extra_iparams
.append("state->storePack.swapEndian")
702 extra_iparams
.append("0")
704 # Hardcode this in. lsb_first param (apparently always GL_FALSE)
705 # also present in GetPolygonStipple, but taken care of above.
706 if xcb_name
== "xcb_glx_read_pixels":
707 extra_iparams
.append("0")
709 iparams
.append(p
.name
)
712 xcb_request
= '%s(%s)' % (xcb_name
, ", ".join(["c", "gc->currentContextTag"] + iparams
+ extra_iparams
))
715 print(' %s_reply_t *reply = %s_reply(c, %s, NULL);' % (xcb_name
, xcb_name
, xcb_request
))
717 if output
.is_image():
718 [dim
, w
, h
, d
, junk
] = output
.get_dimensions()
719 if f
.dimensions_in_reply
:
726 print(' if (%s == 0) { %s = 1; }' % (h
, h
))
730 print(' if (%s == 0) { %s = 1; }' % (d
, d
))
732 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
))
734 if f
.reply_always_array
:
735 print(' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string()))
737 print(' /* the XXX_data_length() xcb function name is misleading, it returns the number */')
738 print(' /* of elements, not the length of the data part. A single element is embedded. */')
739 print(' if (%s_data_length(reply) == 1)' % (xcb_name
))
740 print(' (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output
.name
))
742 print(' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output
.name
, xcb_name
, xcb_name
, output
.get_base_type_string()))
744 if f
.return_type
!= 'void':
745 print(' retval = reply->ret_val;')
746 print(' free(reply);')
748 print(' ' + xcb_request
+ ';')
750 # End of XCB specific.
753 if f
.parameters
!= []:
754 pc_decl
= "GLubyte const * pc ="
758 if name
in f
.glx_vendorpriv_names
:
759 print(' %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl
, f
.opcode_real_name(), f
.opcode_vendor_name(name
)))
761 print(' %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl
, f
.opcode_name()))
763 self
.common_emit_args(f
, "pc", 0, 0)
765 images
= f
.get_images()
769 o
= f
.command_fixed_length() - 4
770 print(' *(int32_t *)(pc + %u) = 0;' % (o
))
771 if img
.img_format
!= "GL_COLOR_INDEX" or img
.img_type
!= "GL_BITMAP":
772 print(' * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o
))
775 print(' * (int8_t *)(pc + %u) = %s;' % (o
+ 1, f
.img_reset
))
780 if f
.return_type
!= 'void':
781 return_name
= " retval"
782 return_str
= " retval = (%s)" % (f
.return_type
)
784 return_str
= " (void)"
788 for p
in f
.parameterIterateOutputs():
790 [dim
, w
, h
, d
, junk
] = p
.get_dimensions()
791 if f
.dimensions_in_reply
:
792 print(" __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim
, p
.img_format
, p
.img_type
, p
.name
))
794 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
))
798 if f
.reply_always_array
:
803 # gl_parameter.size() returns the size
804 # of the entire data item. If the
805 # item is a fixed-size array, this is
806 # the size of the whole array. This
807 # is not what __glXReadReply wants. It
808 # wants the size of a single data
809 # element in the reply packet.
810 # Dividing by the array size (1 for
811 # non-arrays) gives us this.
813 s
= p
.size() / p
.get_element_count()
814 print(" %s __glXReadReply(dpy, %s, %s, %s);" % (return_str
, s
, p
.name
, aa
))
818 # If a reply wasn't read to fill an output parameter,
819 # read a NULL reply to get the return value.
822 print(" %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str
))
826 # Only emit the extra glFinish call for functions
827 # that don't already require a reply from the server.
828 print(' __indirect_glFinish();')
831 print(' printf( "Exit %%s.\\n", "gl%s" );' % (name
))
834 print(' UnlockDisplay(dpy); SyncHandle();')
836 if name
not in f
.glx_vendorpriv_names
:
837 print('#endif /* USE_XCB */')
840 print(' return%s;' % (return_name
))
844 def printPixelFunction(self
, f
):
845 if f
.name
in self
.pixel_stubs
:
846 # Normally gl_function::get_parameter_string could be
847 # used. However, this call needs to have the missing
848 # dimensions (e.g., a fake height value for
849 # glTexImage1D) added in.
852 for param
in f
.parameterIterateGlxSend():
856 p_string
+= ", " + param
.name
859 [dim
, junk
, junk
, junk
, junk
] = param
.get_dimensions()
861 if f
.pad_after(param
):
864 print(' %s(%s, %u%s );' % (self
.pixel_stubs
[f
.name
] , f
.opcode_name(), dim
, p_string
))
868 if self
.common_func_print_just_start(f
, None):
875 print('if (cmdlen <= gc->maxSmallRenderCommandSize) {')
876 print(' if ( (gc->pc + cmdlen) > gc->bufEnd ) {')
877 print(' (void) __glXFlushRenderBuffer(gc, gc->pc);')
883 opcode
= f
.opcode_real_name()
885 print('emit_header(gc->pc, %s, cmdlen);' % (opcode
))
887 self
.pixel_emit_args( f
, "gc->pc", 0 )
888 print('gc->pc += cmdlen;')
889 print('if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }')
895 self
.large_emit_begin(f
, opcode
)
896 self
.pixel_emit_args(f
, "pc", 1)
900 if trailer
: print(trailer
)
904 def printRenderFunction(self
, f
):
905 # There is a class of GL functions that take a single pointer
906 # as a parameter. This pointer points to a fixed-size chunk
907 # of data, and the protocol for this functions is very
908 # regular. Since they are so regular and there are so many
909 # of them, special case them with generic functions. On
910 # x86, this saves about 26KB in the libGL.so binary.
912 if f
.variable_length_parameter() == None and len(f
.parameters
) == 1:
915 cmdlen
= f
.command_fixed_length()
916 if cmdlen
in self
.generic_sizes
:
917 print(' generic_%u_byte( %s, %s );' % (cmdlen
, f
.opcode_real_name(), p
.name
))
920 if self
.common_func_print_just_start(f
, None):
926 print('printf( "Enter %%s...\\n", "gl%s" );' % (f
.name
))
929 print('if (cmdlen <= gc->maxSmallRenderCommandSize) {')
930 print(' if ( (gc->pc + cmdlen) > gc->bufEnd ) {')
931 print(' (void) __glXFlushRenderBuffer(gc, gc->pc);')
934 print('emit_header(gc->pc, %s, cmdlen);' % (f
.opcode_real_name()))
936 self
.common_emit_args(f
, "gc->pc", 4, 0)
937 print('gc->pc += cmdlen;')
938 print('if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }')
944 self
.large_emit_begin(f
)
945 self
.common_emit_args(f
, "pc", 8, 1)
947 p
= f
.variable_length_parameter()
948 print(' __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (p
.offset
+ 8, p
.name
, p
.size_string()))
952 print('__indirect_glFinish();')
953 print('printf( "Exit %%s.\\n", "gl%s" );' % (f
.name
))
955 if trailer
: print(trailer
)
959 class PrintGlxProtoInit_c(gl_XML
.gl_print_base
):
961 gl_XML
.gl_print_base
.__init
__(self
)
963 self
.name
= "glX_proto_send.py (from Mesa)"
964 self
.license
= license
.bsd_license_template
% ( \
965 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
966 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
970 def printRealHeader(self
):
972 * \\file indirect_init.c
973 * Initialize indirect rendering dispatch table.
975 * \\author Kevin E. Martin <kevin@precisioninsight.com>
976 * \\author Brian Paul <brian@precisioninsight.com>
977 * \\author Ian Romanick <idr@us.ibm.com>
980 #include "indirect_init.h"
981 #include "indirect.h"
985 #ifndef GLX_USE_APPLEGL
988 * No-op function used to initialize functions that have no GLX protocol
991 static int NoOp(void)
997 * Create and initialize a new GL dispatch table. The table is initialized
998 * with GLX indirect rendering protocol functions.
1000 struct _glapi_table * __glXNewIndirectAPI( void )
1007 entries = _glapi_get_dispatch_table_size();
1008 table = malloc(entries * sizeof(_glapi_proc));
1012 /* first, set all entries to point to no-op functions */
1013 for (i = 0; i < entries; i++) {
1014 table[i] = (_glapi_proc) NoOp;
1017 /* now, initialize the entries we understand */""")
1019 def printRealFooter(self
):
1021 return (struct _glapi_table *) table;
1029 def printBody(self
, api
):
1030 for [name
, number
] in api
.categoryIterate():
1032 preamble
= '\n /* %3u. %s */\n' % (int(number
), name
)
1034 preamble
= '\n /* %s */\n' % (name
)
1036 for func
in api
.functionIterateByCategory(name
):
1037 if func
.client_supported_for_indirect():
1043 print(' table[{offset}] = (_glapi_proc) __indirect_gl{name};'.format(name
= func
.name
, offset
= func
.offset
))
1045 print(' o = _glapi_get_proc_offset("gl{0}");'.format(func
.name
))
1046 print(' assert(o > 0);')
1047 print(' table[o] = (_glapi_proc) __indirect_gl{0};'.format(func
.name
))
1052 class PrintGlxProtoInit_h(gl_XML
.gl_print_base
):
1054 gl_XML
.gl_print_base
.__init
__(self
)
1056 self
.name
= "glX_proto_send.py (from Mesa)"
1057 self
.license
= license
.bsd_license_template
% ( \
1058 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
1059 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
1060 self
.header_tag
= "_INDIRECT_H_"
1062 self
.last_category
= ""
1066 def printRealHeader(self
):
1069 * Prototypes for indirect rendering functions.
1071 * \\author Kevin E. Martin <kevin@precisioninsight.com>
1072 * \\author Ian Romanick <idr@us.ibm.com>
1075 self
.printFastcall()
1076 self
.printNoinline()
1079 #include <X11/Xfuncproto.h>
1080 #include "glxclient.h"
1082 extern _X_HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
1083 void * dest, GLboolean reply_is_always_array );
1085 extern _X_HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
1086 struct glx_context * gc, unsigned max_dim, GLint width, GLint height,
1087 GLint depth, GLenum format, GLenum type, void * dest,
1088 GLboolean dimensions_in_reply );
1090 extern _X_HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
1091 struct glx_context * gc, GLint sop, GLint cmdlen );
1093 extern _X_HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
1094 struct glx_context * gc, GLint code, GLint vop, GLint cmdlen );
1098 def printBody(self
, api
):
1099 for func
in api
.functionIterateGlx():
1100 params
= func
.get_parameter_string()
1102 print('extern _X_HIDDEN %s __indirect_gl%s(%s);' % (func
.return_type
, func
.name
, params
))
1104 for n
in func
.entry_points
:
1105 if func
.has_different_protocol(n
):
1106 asdf
= func
.static_glx_name(n
)
1107 if asdf
not in func
.static_entry_points
:
1108 print('extern _X_HIDDEN %s gl%s(%s);' % (func
.return_type
, asdf
, params
))
1109 # give it a easy-to-remember name
1110 if func
.client_handcode
:
1111 print('#define gl_dispatch_stub_%s gl%s' % (n
, asdf
))
1113 print('GLAPI %s GLAPIENTRY gl%s(%s);' % (func
.return_type
, asdf
, params
))
1118 print('#ifdef GLX_INDIRECT_RENDERING')
1119 print('extern _X_HIDDEN void (*__indirect_get_proc_address(const char *name))(void);')
1124 """Parse input and returned a parsed namespace."""
1125 parser
= argparse
.ArgumentParser()
1126 parser
.add_argument('-f',
1127 default
='gl_API.xml',
1129 help='An XML file describing an API')
1130 parser
.add_argument('-m',
1133 choices
=frozenset(['proto', 'init_c', 'init_h']),
1134 help='which file to generate')
1135 parser
.add_argument('-d',
1136 action
='store_true',
1138 help='turn debug mode on.')
1139 return parser
.parse_args()
1143 """Main function."""
1146 if args
.mode
== "proto":
1147 printer
= PrintGlxProtoStubs()
1148 elif args
.mode
== "init_c":
1149 printer
= PrintGlxProtoInit_c()
1150 elif args
.mode
== "init_h":
1151 printer
= PrintGlxProtoInit_h()
1153 printer
.debug
= args
.debug
1154 api
= gl_XML
.parse_GL_API(args
.filename
, glX_XML
.glx_item_factory())
1156 printer
.Print( api
)
1159 if __name__
== '__main__':