Generate server-side GLX protocol decode functions using the 'make server'

target.  The environment variable XORG_BASE must be set to point to the base
of the X.org server sources where the files are to be placed.

The 7.0.0 server release already contains files generated by these scripts.
The scripts should have been committed months ago.  Sorry for the lag. :(
This commit is contained in:
Ian Romanick
2006-03-06 18:30:17 +00:00
parent 448d23331d
commit 9d881ea718
3 changed files with 588 additions and 2 deletions
+25
View File
@@ -18,11 +18,21 @@ OUTPUTS = glprocs.h glapitemp.h glapioffsets.h glapitable.h dispatch.h \
../../glx/x11/indirect_size.h \
../../glx/x11/indirect_size.c
#XORG_BASE = /home/idr/devel/graphics/Xorg/xserver/xorg
GLX_DIR = $(XORG_BASE)/GL/glx
SERVER_OUTPUTS = $(GLX_DIR)/indirect_dispatch.c \
$(GLX_DIR)/indirect_dispatch_swap.c \
$(GLX_DIR)/indirect_dispatch.h
COMMON = gl_XML.py license.py gl_API.xml typeexpr.py
COMMON_GLX = $(COMMON) glX_XML.py glX_proto_common.py
all: $(OUTPUTS)
server: $(SERVER_OUTPUTS)
glprocs.h: $(COMMON) gl_procs.py
$(PYTHON2) $(PYTHON_FLAGS) gl_procs.py > glprocs.h
@@ -65,6 +75,21 @@ dispatch.h: $(COMMON) gl_table.py
../../glx/x11/indirect_size.c: $(COMMON_GLX) glX_proto_size.py
$(PYTHON2) $(PYTHON_FLAGS) glX_proto_size.py -m size_c --only-set > ../../glx/x11/indirect_size.c
$(GLX_DIR)/indirect_dispatch.c: $(COMMON_GLX) glX_proto_recv.py
$(PYTHON2) $(PYTHON_FLAGS) glX_proto_recv.py -m dispatch_c > $@
$(GLX_DIR)/indirect_dispatch_swap.c: $(COMMON_GLX) glX_proto_recv.py
$(PYTHON2) $(PYTHON_FLAGS) glX_proto_recv.py -m dispatch_c -s > $@
$(GLX_DIR)/indirect_dispatch.h: $(COMMON_GLX) glX_proto_recv.py
$(PYTHON2) $(PYTHON_FLAGS) glX_proto_recv.py -m dispatch_h -s > $@
$(GLX_DIR)/indirect_size_get.h: $(COMMON_GLX) glX_proto_size.py
$(PYTHON2) $(PYTHON_FLAGS) glX_proto_size.py -m size_h --only-get -h '_INDIRECT_SIZE_GET_H_' > $@
$(GLX_DIR)/indirect_size_get.c: $(COMMON_GLX) glX_proto_size.py
$(PYTHON2) $(PYTHON_FLAGS) glX_proto_size.py -m size_c > $@
clean:
rm -f *~ *.pyo
rm -f $(OUTPUTS)
+2 -2
View File
@@ -48,7 +48,7 @@ class glx_proto_type(gl_XML.gl_type):
class glx_print_proto(gl_XML.gl_print_base):
def size_call(self, func):
def size_call(self, func, outputs_also = 0):
"""Create C code to calculate 'compsize'.
Creates code to calculate 'compsize'. If the function does
@@ -58,7 +58,7 @@ class glx_print_proto(gl_XML.gl_print_base):
compsize = None
for param in func.parameterIterator():
if not param.is_output:
if outputs_also or not param.is_output:
if param.is_image():
[dim, w, h, d, junk] = param.get_dimensions()
+561
View File
@@ -0,0 +1,561 @@
#!/usr/bin/env python
# (C) Copyright IBM Corporation 2005
# All Rights Reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# on the rights to use, copy, modify, merge, publish, distribute, sub
# license, and/or sell copies of the Software, and to permit persons to whom
# the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# Authors:
# Ian Romanick <idr@us.ibm.com>
import gl_XML, glX_XML, glX_proto_common, license
import sys, getopt, string
class PrintGlxDispatch_h(gl_XML.gl_print_base):
def __init__(self):
gl_XML.gl_print_base.__init__(self)
self.name = "glX_proto_recv.py (from Mesa)"
self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2005", "IBM")
self.header_tag = "_INDIRECT_DISPATCH_H_"
return
def printRealHeader(self):
self.printVisibility( "HIDDEN", "hidden" )
print 'struct __GLXclientStateRec;'
print ''
return
def printBody(self, api):
for func in api.functionIterateAll():
if not func.ignore and not func.vectorequiv:
if func.glx_rop != 0:
print 'extern HIDDEN void __glXDisp_%s(GLbyte * pc);' % (func.name)
print 'extern HIDDEN void __glXDispSwap_%s(GLbyte * pc);' % (func.name)
elif func.glx_sop != 0 or func.glx_vendorpriv != 0:
print 'extern HIDDEN int __glXDisp_%s(struct __GLXclientStateRec *, GLbyte *);' % (func.name)
print 'extern HIDDEN int __glXDispSwap_%s(struct __GLXclientStateRec *, GLbyte *);' % (func.name)
return
class PrintGlxDispatchFunctions(glX_proto_common.glx_print_proto):
def __init__(self, do_swap):
gl_XML.gl_print_base.__init__(self)
self.name = "glX_proto_recv.py (from Mesa)"
self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2005", "IBM")
self.real_types = [ '', '', 'uint16_t', '', 'uint32_t', '', '', '', 'uint64_t' ]
self.do_swap = do_swap
return
def printRealHeader(self):
print '#include <X11/Xmd.h>'
print '#include <GL/gl.h>'
print '#include <GL/glxproto.h>'
# FIXME: Since this block will require changes as other
# FIXME: platforms are added, it should probably be in a
# FIXME: header file that is not generated by a script.
if self.do_swap:
print '#ifdef __linux__'
print '#include <byteswap.h>'
print '#elif defined(__OpenBSD__)'
print '#include <sys/endian.h>'
print '#define bswap_16 __swap16'
print '#define bswap_32 __swap32'
print '#define bswap_64 __swap64'
print '#else'
print '#include <sys/endian.h>'
print '#define bswap_16 bswap16'
print '#define bswap_32 bswap32'
print '#define bswap_64 bswap64'
print '#endif'
print '#include <inttypes.h>'
print '#include "indirect_size.h"'
print '#include "indirect_size_get.h"'
print '#include "indirect_dispatch.h"'
print '#include "glxserver.h"'
print '#include "indirect_util.h"'
print '#include "singlesize.h"'
print '#include "glapitable.h"'
print '#include "glapi.h"'
print '#include "glthread.h"'
print '#include "dispatch.h"'
print ''
print '#define __GLX_PAD(x) (((x) + 3) & ~3)'
print ''
print 'typedef struct {'
print ' __GLX_PIXEL_3D_HDR;'
print '} __GLXpixel3DHeader;'
print ''
print 'extern GLboolean __glXErrorOccured( void );'
print 'extern void __glXClearErrorOccured( void );'
print ''
print 'static const unsigned dummy_answer[2] = {0, 0};'
print ''
return
def printBody(self, api):
if self.do_swap:
self.emit_swap_wrappers(api)
for func in api.functionIterateByOffset():
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):
self.printFunction(func)
return
def printFunction(self, f):
if (f.glx_sop or f.glx_vendorpriv) and (len(f.get_images()) != 0):
return
if not self.do_swap:
base = '__glXDisp'
else:
base = '__glXDispSwap'
if f.glx_rop:
print 'void %s_%s(GLbyte * pc)' % (base, f.name)
else:
print 'int %s_%s(__GLXclientState *cl, GLbyte *pc)' % (base, f.name)
print '{'
if f.glx_rop or f.vectorequiv:
self.printRenderFunction(f)
elif f.glx_sop or f.glx_vendorpriv:
if len(f.get_images()) == 0:
self.printSingleFunction(f)
else:
print "/* Missing GLX protocol for %s. */" % (f.name)
print '}'
print ''
return
def swap_name(self, bytes):
return 'bswap_%u_array' % (8 * bytes)
def emit_swap_wrappers(self, api):
self.type_map = {}
already_done = [ ]
for t in api.typeIterate():
te = t.get_type_expression()
t_size = te.get_element_size()
if t_size > 1 and t.glx_name:
t_name = "GL" + t.name
self.type_map[ t_name ] = t.glx_name
if t.glx_name not in already_done:
real_name = self.real_types[t_size]
print 'static %s' % (t_name)
print 'bswap_%s( const void * src )' % (t.glx_name)
print '{'
print ' union { %s dst; %s ret; } x;' % (real_name, t_name)
print ' x.dst = bswap_%u( *(%s *) src );' % (t_size * 8, real_name)
print ' return x.ret;'
print '}'
print ''
already_done.append( t.glx_name )
for bits in [16, 32, 64]:
print 'static void *'
print 'bswap_%u_array( uint%u_t * src, unsigned count )' % (bits, bits)
print '{'
print ' unsigned i;'
print ''
print ' for ( i = 0 ; i < count ; i++ ) {'
print ' uint%u_t temp = bswap_%u( src[i] );' % (bits, bits)
print ' src[i] = temp;'
print ' }'
print ''
print ' return src;'
print '}'
print ''
def fetch_param(self, param):
t = param.type_string()
o = param.offset
element_size = param.size() / param.get_element_count()
if self.do_swap and (element_size != 1):
if param.is_array():
real_name = self.real_types[ element_size ]
swap_func = self.swap_name( element_size )
return ' (%-8s)%s( (%s *) (pc + %2s), %s )' % (t, swap_func, real_name, o, param.count)
else:
t_name = param.get_base_type_string()
return ' (%-8s)bswap_%-7s( pc + %2s )' % (t, self.type_map[ t_name ], o)
else:
if param.is_array():
return ' (%-8s)(pc + %2u)' % (t, o)
else:
return '*(%-8s *)(pc + %2u)' % (t, o)
return None
def emit_function_call(self, f, retval_assign, indent):
list = []
for param in f.parameterIterator():
if param.is_counter or param.is_image() or param.is_output or len(param.count_parameter_list):
location = param.name
else:
location = self.fetch_param(param)
list.append( '%s %s' % (indent, location) )
if len( list ):
print '%s %sCALL_%s( GET_DISPATCH(), (' % (indent, retval_assign, f.name)
print string.join( list, ",\n" )
print '%s ) );' % (indent)
else:
print '%s %sCALL_%s( GET_DISPATCH(), () );' % (indent, retval_assign, f.name)
return
def common_func_print_just_start(self, f, indent):
align64 = 0
need_blank = 0
f.calculate_offsets()
for param in f.parameterIterateGlxSend():
# If any parameter has a 64-bit base type, then we
# have to do alignment magic for the while thing.
if param.is_64_bit():
align64 = 1
# FIXME img_null_flag is over-loaded. In addition to
# FIXME being used for images, it is used to signify
# FIXME NULL data pointers for vertex buffer object
# FIXME related functions. Re-name it to null_data
# FIXME or something similar.
if param.img_null_flag:
print '%s const CARD32 ptr_is_null = *(CARD32 *)(pc + %s);' % (indent, param.offset - 4)
cond = '(ptr_is_null != 0) ? NULL : '
else:
cond = ""
type_string = param.type_string()
if param.is_image():
offset = f.offset_of( param.name )
print '%s %s const %s = (%s) %s(pc + %s);' % (indent, type_string, param.name, type_string, cond, offset)
if param.depth:
print '%s __GLXpixel3DHeader * const hdr = (__GLXpixel3DHeader *)(pc);' % (indent)
else:
print '%s __GLXpixelHeader * const hdr = (__GLXpixelHeader *)(pc);' % (indent)
need_blank = 1
elif param.is_counter or param.name in f.count_parameter_list:
location = self.fetch_param(param)
print '%s const %s %s = %s;' % (indent, type_string, param.name, location)
need_blank = 1
elif len(param.count_parameter_list):
if param.size() == 1 and not self.do_swap:
location = self.fetch_param(param)
print '%s %s %s = %s%s;' % (indent, type_string, param.name, cond, location)
else:
print '%s %s %s;' % (indent, type_string, param.name)
need_blank = 1
if need_blank:
print ''
if align64:
print '#ifdef __GLX_ALIGN64'
if f.has_variable_size_request():
self.emit_packet_size_calculation(f, 4)
s = "cmdlen"
else:
s = str((f.command_fixed_length() + 3) & ~3)
print ' if ((unsigned long)(pc) & 7) {'
print ' (void) memmove(pc-4, pc, %s);' % (s)
print ' pc -= 4;'
print ' }'
print '#endif'
print ''
need_blank = 0
if self.do_swap:
for param in f.parameterIterateGlxSend():
if param.count_parameter_list:
o = param.offset
count = param.get_element_count()
type_size = param.size() / count
if param.counter:
count_name = param.counter
else:
count_name = str(count)
# This is basically an ugly special-
# case for glCallLists.
if type_size == 1:
x = []
x.append( [1, ['BYTE', 'UNSIGNED_BYTE', '2_BYTES', '3_BYTES', '4_BYTES']] )
x.append( [2, ['SHORT', 'UNSIGNED_SHORT']] )
x.append( [4, ['INT', 'UNSIGNED_INT', 'FLOAT']] )
print ' switch(%s) {' % (param.count_parameter_list[0])
for sub in x:
for t_name in sub[1]:
print ' case GL_%s:' % (t_name)
if sub[0] == 1:
print ' %s = (%s) (pc + %s); break;' % (param.name, param.type_string(), o)
else:
swap_func = self.swap_name(sub[0])
print ' %s = (%s) %s( (%s *) (pc + %s), %s ); break;' % (param.name, param.type_string(), swap_func, self.real_types[sub[0]], o, count_name)
print ' }'
else:
swap_func = self.swap_name(type_size)
compsize = self.size_call(f, 1)
print ' %s = (%s) %s( (%s *) (pc + %s), %s );' % (param.name, param.type_string(), swap_func, self.real_types[type_size], o, compsize)
need_blank = 1
else:
for param in f.parameterIterateGlxSend():
if param.count_parameter_list:
print '%s %s = (%s) (pc + %s);' % (indent, param.name, param.type_string(), param.offset)
need_blank = 1
if need_blank:
print ''
return
def printSingleFunction(self, f):
if f.glx_sop:
print ' xGLXSingleReq * const req = (xGLXSingleReq *) pc;'
else:
print ' xGLXVendorPrivateReq * const req = (xGLXVendorPrivateReq *) pc;'
print ' int error;'
if self.do_swap:
print ' __GLXcontext * const cx = __glXForceCurrent(cl, bswap_CARD32( &req->contextTag ), &error);'
else:
print ' __GLXcontext * const cx = __glXForceCurrent(cl, req->contextTag, &error);'
print ''
if f.glx_sop:
print ' pc += __GLX_SINGLE_HDR_SIZE;'
else:
print ' pc += __GLX_VENDPRIV_HDR_SIZE;'
print ' if ( cx != NULL ) {'
self.common_func_print_just_start(f, " ")
if f.return_type != 'void':
print ' %s retval;' % (f.return_type)
retval_string = "retval"
retval_assign = "retval = "
else:
retval_string = "0"
retval_assign = ""
type_size = 0
answer_string = "dummy_answer"
answer_count = "0"
is_array_string = "GL_FALSE"
for param in f.parameterIterateOutputs():
answer_type = param.get_base_type_string()
if answer_type == "GLvoid":
answer_type = "GLubyte"
c = param.get_element_count()
type_size = (param.size() / c)
if type_size == 1:
size_scale = ""
else:
size_scale = " * %u" % (type_size)
if param.count_parameter_list:
print ' const GLuint compsize = %s;' % (self.size_call(f, 1))
print ' %s answerBuffer[200];' % (answer_type)
print ' %s %s = __glXGetAnswerBuffer(cl, compsize%s, answerBuffer, sizeof(answerBuffer), %u);' % (param.type_string(), param.name, size_scale, type_size )
answer_string = param.name
answer_count = "compsize"
print ''
print ' if (%s == NULL) return BadAlloc;' % (param.name)
print ' __glXClearErrorOccured();'
print ''
elif param.counter:
print ' %s answerBuffer[200];' % (answer_type)
print ' %s %s = __glXGetAnswerBuffer(cl, %s%s, answerBuffer, sizeof(answerBuffer), %u);' % (param.type_string(), param.name, param.counter, size_scale, type_size)
answer_string = param.name
answer_count = param.counter
elif c >= 1:
print ' %s %s[%u];' % (answer_type, param.name, c)
answer_string = param.name
answer_count = "%u" % (c)
if f.reply_always_array:
is_array_string = "GL_TRUE"
self.emit_function_call(f, retval_assign, " ")
if f.needs_reply():
if self.do_swap:
for param in f.parameterIterateOutputs():
c = param.get_element_count()
type_size = (param.size() / c)
if type_size > 1:
swap_name = self.swap_name( type_size )
print ' (void) %s( (uint%u_t *) %s, %s );' % (swap_name, 8 * type_size, param.name, answer_count)
reply_func = '__glXSendReplySwap'
else:
reply_func = '__glXSendReply'
print ' %s(cl->client, %s, %s, %u, %s, %s);' % (reply_func, answer_string, answer_count, type_size, is_array_string, retval_string)
#elif f.note_unflushed:
# print ' cx->hasUnflushedCommands = GL_TRUE;'
print ' error = Success;'
print ' }'
print ''
print ' return error;'
return
def printRenderFunction(self, f):
# There are 4 distinct phases in a rendering dispatch function.
# In the first phase we compute the sizes and offsets of each
# element in the command. In the second phase we (optionally)
# re-align 64-bit data elements. In the third phase we
# (optionally) byte-swap array data. Finally, in the fourth
# phase we actually dispatch the function.
self.common_func_print_just_start(f, "")
images = f.get_images()
if len(images):
if self.do_swap:
pre = "bswap_CARD32( & "
post = " )"
else:
pre = ""
post = ""
img = images[0]
# swapBytes and lsbFirst are single byte fields, so
# the must NEVER be byte-swapped.
if not (img.img_type == "GL_BITMAP" and img.img_format == "GL_COLOR_INDEX"):
print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SWAP_BYTES, hdr->swapBytes) );'
print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_LSB_FIRST, hdr->lsbFirst) );'
print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH, (GLint) %shdr->rowLength%s) );' % (pre, post)
if img.depth:
print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_IMAGE_HEIGHT, (GLint) %shdr->imageHeight%s) );' % (pre, post)
print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS, (GLint) %shdr->skipRows%s) );' % (pre, post)
if img.depth:
print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_IMAGES, (GLint) %shdr->skipImages%s) );' % (pre, post)
print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS, (GLint) %shdr->skipPixels%s) );' % (pre, post)
print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ALIGNMENT, (GLint) %shdr->alignment%s) );' % (pre, post)
print ''
self.emit_function_call(f, "", "")
return
if __name__ == '__main__':
file_name = "gl_API.xml"
try:
(args, trail) = getopt.getopt(sys.argv[1:], "f:m:s")
except Exception,e:
show_usage()
mode = "dispatch_c"
do_swap = 0
for (arg,val) in args:
if arg == "-f":
file_name = val
elif arg == "-m":
mode = val
elif arg == "-s":
do_swap = 1
if mode == "dispatch_c":
printer = PrintGlxDispatchFunctions(do_swap)
elif mode == "dispatch_h":
printer = PrintGlxDispatch_h()
else:
show_usage()
api = gl_XML.parse_GL_API( file_name, glX_proto_common.glx_proto_item_factory() )
printer.Print( api )