3 # (C) Copyright IBM Corporation 2005
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>
28 import gl_XML
, glX_XML
, glX_proto_common
, license
29 import sys
, getopt
, string
32 class PrintGlxDispatch_h(gl_XML
.gl_print_base
):
34 gl_XML
.gl_print_base
.__init
__(self
)
36 self
.name
= "glX_proto_recv.py (from Mesa)"
37 self
.license
= license
.bsd_license_template
% ( "(C) Copyright IBM Corporation 2005", "IBM")
39 self
.header_tag
= "_INDIRECT_DISPATCH_H_"
43 def printRealHeader(self
):
44 self
.printVisibility( "HIDDEN", "hidden" )
45 print 'struct __GLXclientStateRec;'
50 def printBody(self
, api
):
51 for func
in api
.functionIterateAll():
52 if not func
.ignore
and not func
.vectorequiv
:
54 print 'extern HIDDEN void __glXDisp_%s(GLbyte * pc);' % (func
.name
)
55 print 'extern HIDDEN void __glXDispSwap_%s(GLbyte * pc);' % (func
.name
)
56 elif func
.glx_sop
or func
.glx_vendorpriv
:
57 print 'extern HIDDEN int __glXDisp_%s(struct __GLXclientStateRec *, GLbyte *);' % (func
.name
)
58 print 'extern HIDDEN int __glXDispSwap_%s(struct __GLXclientStateRec *, GLbyte *);' % (func
.name
)
60 if func
.glx_sop
and func
.glx_vendorpriv
:
61 n
= func
.glx_vendorpriv_names
[0]
62 print 'extern HIDDEN int __glXDisp_%s(struct __GLXclientStateRec *, GLbyte *);' % (n
)
63 print 'extern HIDDEN int __glXDispSwap_%s(struct __GLXclientStateRec *, GLbyte *);' % (n
)
68 class PrintGlxDispatchFunctions(glX_proto_common
.glx_print_proto
):
69 def __init__(self
, do_swap
):
70 gl_XML
.gl_print_base
.__init
__(self
)
71 self
.name
= "glX_proto_recv.py (from Mesa)"
72 self
.license
= license
.bsd_license_template
% ( "(C) Copyright IBM Corporation 2005", "IBM")
74 self
.real_types
= [ '', '', 'uint16_t', '', 'uint32_t', '', '', '', 'uint64_t' ]
75 self
.do_swap
= do_swap
79 def printRealHeader(self
):
80 print '#include <X11/Xmd.h>'
81 print '#include <GL/gl.h>'
82 print '#include <GL/glxproto.h>'
85 # FIXME: Since this block will require changes as other
86 # FIXME: platforms are added, it should probably be in a
87 # FIXME: header file that is not generated by a script.
90 print '#ifdef __linux__'
91 print '#include <byteswap.h>'
92 print '#elif defined(__OpenBSD__)'
93 print '#include <sys/endian.h>'
94 print '#define bswap_16 __swap16'
95 print '#define bswap_32 __swap32'
96 print '#define bswap_64 __swap64'
98 print '#include <sys/endian.h>'
99 print '#define bswap_16 bswap16'
100 print '#define bswap_32 bswap32'
101 print '#define bswap_64 bswap64'
104 print '#include <inttypes.h>'
105 print '#include "indirect_size.h"'
106 print '#include "indirect_size_get.h"'
107 print '#include "indirect_dispatch.h"'
108 print '#include "glxserver.h"'
109 print '#include "indirect_util.h"'
110 print '#include "singlesize.h"'
111 print '#include "glapitable.h"'
112 print '#include "glapi.h"'
113 print '#include "glthread.h"'
114 print '#include "dispatch.h"'
116 print '#define __GLX_PAD(x) (((x) + 3) & ~3)'
118 print 'typedef struct {'
119 print ' __GLX_PIXEL_3D_HDR;'
120 print '} __GLXpixel3DHeader;'
122 print 'extern GLboolean __glXErrorOccured( void );'
123 print 'extern void __glXClearErrorOccured( void );'
125 print 'static const unsigned dummy_answer[2] = {0, 0};'
130 def printBody(self
, api
):
132 self
.emit_swap_wrappers(api
)
135 for func
in api
.functionIterateByOffset():
136 if not func
.ignore
and not func
.server_handcode
and not func
.vectorequiv
and (func
.glx_rop
or func
.glx_sop
or func
.glx_vendorpriv
):
137 self
.printFunction(func
, func
.name
)
138 if func
.glx_sop
and func
.glx_vendorpriv
:
139 self
.printFunction(func
, func
.glx_vendorpriv_names
[0])
145 def printFunction(self
, f
, name
):
146 if (f
.glx_sop
or f
.glx_vendorpriv
) and (len(f
.get_images()) != 0):
152 base
= '__glXDispSwap'
155 print 'void %s_%s(GLbyte * pc)' % (base
, name
)
157 print 'int %s_%s(__GLXclientState *cl, GLbyte *pc)' % (base
, name
)
161 if f
.glx_rop
or f
.vectorequiv
:
162 self
.printRenderFunction(f
)
163 elif f
.glx_sop
or f
.glx_vendorpriv
:
164 if len(f
.get_images()) == 0:
165 self
.printSingleFunction(f
, name
)
167 print "/* Missing GLX protocol for %s. */" % (name
)
174 def swap_name(self
, bytes
):
175 return 'bswap_%u_array' % (8 * bytes
)
178 def emit_swap_wrappers(self
, api
):
182 for t
in api
.typeIterate():
183 te
= t
.get_type_expression()
184 t_size
= te
.get_element_size()
186 if t_size
> 1 and t
.glx_name
:
188 t_name
= "GL" + t
.name
189 self
.type_map
[ t_name
] = t
.glx_name
191 if t
.glx_name
not in already_done
:
192 real_name
= self
.real_types
[t_size
]
194 print 'static %s' % (t_name
)
195 print 'bswap_%s( const void * src )' % (t
.glx_name
)
197 print ' union { %s dst; %s ret; } x;' % (real_name
, t_name
)
198 print ' x.dst = bswap_%u( *(%s *) src );' % (t_size
* 8, real_name
)
199 print ' return x.ret;'
202 already_done
.append( t
.glx_name
)
204 for bits
in [16, 32, 64]:
205 print 'static void *'
206 print 'bswap_%u_array( uint%u_t * src, unsigned count )' % (bits
, bits
)
210 print ' for ( i = 0 ; i < count ; i++ ) {'
211 print ' uint%u_t temp = bswap_%u( src[i] );' % (bits
, bits
)
212 print ' src[i] = temp;'
220 def fetch_param(self
, param
):
221 t
= param
.type_string()
223 element_size
= param
.size() / param
.get_element_count()
225 if self
.do_swap
and (element_size
!= 1):
227 real_name
= self
.real_types
[ element_size
]
229 swap_func
= self
.swap_name( element_size
)
230 return ' (%-8s)%s( (%s *) (pc + %2s), %s )' % (t
, swap_func
, real_name
, o
, param
.count
)
232 t_name
= param
.get_base_type_string()
233 return ' (%-8s)bswap_%-7s( pc + %2s )' % (t
, self
.type_map
[ t_name
], o
)
236 return ' (%-8s)(pc + %2u)' % (t
, o
)
238 return '*(%-8s *)(pc + %2u)' % (t
, o
)
243 def emit_function_call(self
, f
, retval_assign
, indent
):
246 for param
in f
.parameterIterator():
248 if param
.is_counter
or param
.is_image() or param
.is_output
or param
.name
in f
.count_parameter_list
or len(param
.count_parameter_list
):
249 location
= param
.name
251 location
= self
.fetch_param(param
)
253 list.append( '%s %s' % (indent
, location
) )
257 print '%s %sCALL_%s( GET_DISPATCH(), (' % (indent
, retval_assign
, f
.name
)
258 print string
.join( list, ",\n" )
259 print '%s ) );' % (indent
)
261 print '%s %sCALL_%s( GET_DISPATCH(), () );' % (indent
, retval_assign
, f
.name
)
265 def common_func_print_just_start(self
, f
, indent
):
270 f
.calculate_offsets()
271 for param
in f
.parameterIterateGlxSend():
272 # If any parameter has a 64-bit base type, then we
273 # have to do alignment magic for the while thing.
275 if param
.is_64_bit():
279 # FIXME img_null_flag is over-loaded. In addition to
280 # FIXME being used for images, it is used to signify
281 # FIXME NULL data pointers for vertex buffer object
282 # FIXME related functions. Re-name it to null_data
283 # FIXME or something similar.
285 if param
.img_null_flag
:
286 print '%s const CARD32 ptr_is_null = *(CARD32 *)(pc + %s);' % (indent
, param
.offset
- 4)
287 cond
= '(ptr_is_null != 0) ? NULL : '
292 type_string
= param
.type_string()
295 offset
= f
.offset_of( param
.name
)
297 print '%s %s const %s = (%s) %s(pc + %s);' % (indent
, type_string
, param
.name
, type_string
, cond
, offset
)
300 print '%s __GLXpixel3DHeader * const hdr = (__GLXpixel3DHeader *)(pc);' % (indent
)
302 print '%s __GLXpixelHeader * const hdr = (__GLXpixelHeader *)(pc);' % (indent
)
305 elif param
.is_counter
or param
.name
in f
.count_parameter_list
:
306 location
= self
.fetch_param(param
)
307 print '%s const %s %s = %s;' % (indent
, type_string
, param
.name
, location
)
309 elif len(param
.count_parameter_list
):
310 if param
.size() == 1 and not self
.do_swap
:
311 location
= self
.fetch_param(param
)
312 print '%s %s %s = %s%s;' % (indent
, type_string
, param
.name
, cond
, location
)
314 print '%s %s %s;' % (indent
, type_string
, param
.name
)
323 print '#ifdef __GLX_ALIGN64'
325 if f
.has_variable_size_request():
326 self
.emit_packet_size_calculation(f
, 4)
329 s
= str((f
.command_fixed_length() + 3) & ~
3)
331 print ' if ((unsigned long)(pc) & 7) {'
332 print ' (void) memmove(pc-4, pc, %s);' % (s
)
341 for param
in f
.parameterIterateGlxSend():
342 if param
.count_parameter_list
:
344 count
= param
.get_element_count()
345 type_size
= param
.size() / count
348 count_name
= param
.counter
350 count_name
= str(count
)
352 # This is basically an ugly special-
353 # case for glCallLists.
357 x
.append( [1, ['BYTE', 'UNSIGNED_BYTE', '2_BYTES', '3_BYTES', '4_BYTES']] )
358 x
.append( [2, ['SHORT', 'UNSIGNED_SHORT']] )
359 x
.append( [4, ['INT', 'UNSIGNED_INT', 'FLOAT']] )
361 print ' switch(%s) {' % (param
.count_parameter_list
[0])
363 for t_name
in sub
[1]:
364 print ' case GL_%s:' % (t_name
)
367 print ' %s = (%s) (pc + %s); break;' % (param
.name
, param
.type_string(), o
)
369 swap_func
= self
.swap_name(sub
[0])
370 print ' %s = (%s) %s( (%s *) (pc + %s), %s ); break;' % (param
.name
, param
.type_string(), swap_func
, self
.real_types
[sub
[0]], o
, count_name
)
375 swap_func
= self
.swap_name(type_size
)
376 compsize
= self
.size_call(f
, 1)
377 print ' %s = (%s) %s( (%s *) (pc + %s), %s );' % (param
.name
, param
.type_string(), swap_func
, self
.real_types
[type_size
], o
, compsize
)
382 for param
in f
.parameterIterateGlxSend():
383 if param
.count_parameter_list
:
384 print '%s %s = (%s) (pc + %s);' % (indent
, param
.name
, param
.type_string(), param
.offset
)
395 def printSingleFunction(self
, f
, name
):
396 if name
not in f
.glx_vendorpriv_names
:
397 print ' xGLXSingleReq * const req = (xGLXSingleReq *) pc;'
399 print ' xGLXVendorPrivateReq * const req = (xGLXVendorPrivateReq *) pc;'
404 print ' __GLXcontext * const cx = __glXForceCurrent(cl, bswap_CARD32( &req->contextTag ), &error);'
406 print ' __GLXcontext * const cx = __glXForceCurrent(cl, req->contextTag, &error);'
409 if name
not in f
.glx_vendorpriv_names
:
410 print ' pc += __GLX_SINGLE_HDR_SIZE;'
412 print ' pc += __GLX_VENDPRIV_HDR_SIZE;'
414 print ' if ( cx != NULL ) {'
415 self
.common_func_print_just_start(f
, " ")
418 if f
.return_type
!= 'void':
419 print ' %s retval;' % (f
.return_type
)
420 retval_string
= "retval"
421 retval_assign
= "retval = "
428 answer_string
= "dummy_answer"
430 is_array_string
= "GL_FALSE"
432 for param
in f
.parameterIterateOutputs():
433 answer_type
= param
.get_base_type_string()
434 if answer_type
== "GLvoid":
435 answer_type
= "GLubyte"
438 c
= param
.get_element_count()
439 type_size
= (param
.size() / c
)
443 size_scale
= " * %u" % (type_size
)
446 if param
.count_parameter_list
:
447 print ' const GLuint compsize = %s;' % (self
.size_call(f
, 1))
448 print ' %s answerBuffer[200];' % (answer_type
)
449 print ' %s %s = __glXGetAnswerBuffer(cl, compsize%s, answerBuffer, sizeof(answerBuffer), %u);' % (param
.type_string(), param
.name
, size_scale
, type_size
)
450 answer_string
= param
.name
451 answer_count
= "compsize"
454 print ' if (%s == NULL) return BadAlloc;' % (param
.name
)
455 print ' __glXClearErrorOccured();'
458 print ' %s answerBuffer[200];' % (answer_type
)
459 print ' %s %s = __glXGetAnswerBuffer(cl, %s%s, answerBuffer, sizeof(answerBuffer), %u);' % (param
.type_string(), param
.name
, param
.counter
, size_scale
, type_size
)
460 answer_string
= param
.name
461 answer_count
= param
.counter
463 print ' %s %s[%u];' % (answer_type
, param
.name
, c
)
464 answer_string
= param
.name
465 answer_count
= "%u" % (c
)
467 if f
.reply_always_array
:
468 is_array_string
= "GL_TRUE"
471 self
.emit_function_call(f
, retval_assign
, " ")
476 for param
in f
.parameterIterateOutputs():
477 c
= param
.get_element_count()
478 type_size
= (param
.size() / c
)
481 swap_name
= self
.swap_name( type_size
)
482 print ' (void) %s( (uint%u_t *) %s, %s );' % (swap_name
, 8 * type_size
, param
.name
, answer_count
)
485 reply_func
= '__glXSendReplySwap'
487 reply_func
= '__glXSendReply'
489 print ' %s(cl->client, %s, %s, %u, %s, %s);' % (reply_func
, answer_string
, answer_count
, type_size
, is_array_string
, retval_string
)
490 #elif f.note_unflushed:
491 # print ' cx->hasUnflushedCommands = GL_TRUE;'
493 print ' error = Success;'
496 print ' return error;'
500 def printRenderFunction(self
, f
):
501 # There are 4 distinct phases in a rendering dispatch function.
502 # In the first phase we compute the sizes and offsets of each
503 # element in the command. In the second phase we (optionally)
504 # re-align 64-bit data elements. In the third phase we
505 # (optionally) byte-swap array data. Finally, in the fourth
506 # phase we actually dispatch the function.
508 self
.common_func_print_just_start(f
, "")
510 images
= f
.get_images()
513 pre
= "bswap_CARD32( & "
521 # swapBytes and lsbFirst are single byte fields, so
522 # the must NEVER be byte-swapped.
524 if not (img
.img_type
== "GL_BITMAP" and img
.img_format
== "GL_COLOR_INDEX"):
525 print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SWAP_BYTES, hdr->swapBytes) );'
527 print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_LSB_FIRST, hdr->lsbFirst) );'
529 print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH, (GLint) %shdr->rowLength%s) );' % (pre
, post
)
531 print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_IMAGE_HEIGHT, (GLint) %shdr->imageHeight%s) );' % (pre
, post
)
532 print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS, (GLint) %shdr->skipRows%s) );' % (pre
, post
)
534 print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_IMAGES, (GLint) %shdr->skipImages%s) );' % (pre
, post
)
535 print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS, (GLint) %shdr->skipPixels%s) );' % (pre
, post
)
536 print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ALIGNMENT, (GLint) %shdr->alignment%s) );' % (pre
, post
)
540 self
.emit_function_call(f
, "", "")
544 if __name__
== '__main__':
545 file_name
= "gl_API.xml"
548 (args
, trail
) = getopt
.getopt(sys
.argv
[1:], "f:m:s")
554 for (arg
,val
) in args
:
562 if mode
== "dispatch_c":
563 printer
= PrintGlxDispatchFunctions(do_swap
)
564 elif mode
== "dispatch_h":
565 printer
= PrintGlxDispatch_h()
569 api
= gl_XML
.parse_GL_API( file_name
, glX_proto_common
.glx_proto_item_factory() )