aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xwin/swrastwgl_dri/gen_gl_wrappers.py
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xwin/swrastwgl_dri/gen_gl_wrappers.py')
-rw-r--r--xorg-server/hw/xwin/swrastwgl_dri/gen_gl_wrappers.py327
1 files changed, 327 insertions, 0 deletions
diff --git a/xorg-server/hw/xwin/swrastwgl_dri/gen_gl_wrappers.py b/xorg-server/hw/xwin/swrastwgl_dri/gen_gl_wrappers.py
new file mode 100644
index 000000000..cc66eb096
--- /dev/null
+++ b/xorg-server/hw/xwin/swrastwgl_dri/gen_gl_wrappers.py
@@ -0,0 +1,327 @@
+#!/usr/bin/python
+#
+# Comedy python script to generate cdecl to stdcall wrappers for GL functions
+#
+# This is designed to operate on OpenGL spec files from
+# http://www.opengl.org/registry/api/
+#
+#
+# Copyright (c) Jon TURNEY 2009
+#
+# 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
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
+# THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+#
+# Except as contained in this notice, the name(s) of the above copyright
+# holders shall not be used in advertising or otherwise to promote the sale,
+# use or other dealings in this Software without prior written authorization.
+#
+
+import sys
+import re
+import getopt
+
+dispatchheader = ''
+prefix = 'gl'
+preresolve = False
+staticwrappers = False
+
+opts, args = getopt.getopt(sys.argv[1:], "", ['spec=', 'typemap=', 'dispatch-header=', 'prefix=', 'preresolve', 'staticwrappers' ])
+
+for o,a in opts:
+ if o == '--typemap' :
+ typemapfile = a
+ elif o == '--dispatch-header' :
+ dispatchheader = a
+ elif o == '--spec' :
+ specfile = a
+ elif o == '--prefix' :
+ prefix = a
+ elif o == '--preresolve' :
+ preresolve = True
+ elif o == '--staticwrappers' :
+ staticwrappers = True
+
+#
+# look for all the SET_ macros in dispatch.h, this is the set of functions
+# we need to generate
+#
+
+dispatch = {}
+
+if dispatchheader :
+ fh = open(dispatchheader)
+ dispatchh = fh.readlines()
+
+ dispatch_regex = re.compile(r'(?:#define|static\s+INLINE\s+void)\s+SET_([^\()]+)\(')
+
+ for line in dispatchh :
+ line = line.strip()
+ m1 = dispatch_regex.search(line)
+
+ if m1 :
+ dispatch[m1.group(1)] = 1
+
+ del dispatch['by_offset']
+
+#
+# read the typemap .tm file
+#
+
+typemap = {}
+
+fh = open(typemapfile)
+tm = fh.readlines()
+
+typemap_regex = re.compile(r'#define\sSET_(\S*)\(')
+
+for line in tm :
+ # ignore everything after a '#' as a comment
+ hash = line.find('#')
+ if hash != -1 :
+ line = line[:hash-1]
+
+ # ignore blank lines
+ if line.startswith('#') or len(line) == 0 :
+ continue
+
+ l = line.split(',')
+ typemap[l[0]] = l[3].strip()
+
+# interestingly, * is not a C type
+if typemap['void'] == '*' :
+ typemap['void'] = 'void'
+
+#
+# crudely parse the .spec file
+#
+
+r1 = re.compile(r'\t(\S*)\s+(\S*.*)')
+r2 = re.compile(r'(.*)\((.*)\)')
+r3 = re.compile(r'glWindowPos.*MESA')
+r4 = re.compile(r'gl.*Program(s|)NV')
+r5 = re.compile(r'glGetVertexAttribfvNV')
+
+wrappers = {}
+
+fh = open(specfile)
+glspec = fh.readlines()
+param_count = 0
+
+for line in glspec :
+ line = line.rstrip()
+
+ # ignore everything after a '#' as a comment
+ hash = line.find('#')
+ if hash != -1 :
+ line = line[:hash-1]
+
+ # ignore blank lines
+ if line.startswith('#') or len(line) == 0 :
+ continue
+
+ # lines containing ':' aren't intersting to us
+ if line.count(':') != 0 :
+ continue
+
+ # attributes of each function follow the name, indented by a tab
+ if not line.startswith('\t') :
+ m1 = r2.search(line)
+ if m1 :
+ function = m1.group(1)
+ arglist_use = m1.group(2)
+ wrappers[function] = {}
+
+ # near and far might be reserved words or macros so can't be used as formal parameter names
+ arglist_use = arglist_use.replace('near','zNear')
+ arglist_use = arglist_use.replace('far','zFar')
+
+ wrappers[function]['arglist_use'] = arglist_use
+ param_count = 0
+ else :
+ m1 = r1.search(line)
+ if m1 :
+ attribute = m1.group(1)
+ value = m1.group(2)
+
+ # make param attributes unique and ordered
+ if attribute == 'param' :
+ attribute = 'param' + '%02d' % param_count
+ param_count += 1
+
+ wrappers[function][attribute] = value
+
+#
+# now emit code
+#
+
+print '/* Automatically generated by ' + sys.argv[0] + ' DO NOT EDIT */'
+print '/* from ' + specfile + ' and typemap ' + typemapfile + ' */'
+print ''
+
+#
+# if required, emit code for non-lazy function resolving
+#
+
+if preresolve :
+ for w in sorted(wrappers.keys()) :
+ funcname = prefix + w
+ print 'RESOLVE_DECL(PFN' + funcname.upper() + 'PROC);'
+
+ print ''
+ print 'void ' + prefix + 'ResolveExtensionProcs(void)'
+ print '{'
+
+ for w in sorted(wrappers.keys()) :
+ funcname = prefix + w
+ print ' PRERESOLVE(PFN' + funcname.upper() + 'PROC, "' + funcname + '");'
+
+ print '}\n'
+
+#
+# now emit the wrappers
+# for GL 1.0 and 1.1 functions, generate stdcall wrappers which call the function directly
+# for GL 1.2+ functions, generate wrappers which use wglGetProcAddress()
+#
+
+for w in sorted(wrappers.keys()) :
+
+ funcname = prefix + w
+ returntype = wrappers[w]['return']
+ if returntype != 'void' :
+ returntype = typemap[returntype]
+
+ # Avoid generating wrappers which aren't referenced by the dispatch table
+ if dispatchheader and not dispatch.has_key(w) :
+ print '/* No wrapper for ' + funcname + ', not in dispatch table */'
+ continue
+
+ # manufacture arglist
+ # if no param attributes were found, it should be 'void'
+ al = []
+ for k in sorted(wrappers[w].keys()) :
+ if k.startswith('param') :
+ l = wrappers[w][k].split()
+
+ # near and far might be reserved words or macros so can't be used as formal parameter names
+ l[0] = l[0].replace('near','zNear')
+ l[0] = l[0].replace('far','zFar')
+
+ if l[2] == 'in' :
+ if l[3] == 'array' :
+ arg = 'const ' + typemap[l[1]] + ' *' + l[0]
+ elif l[3] == 'reference' :
+ arg = 'const ' + typemap[l[1]] + ' *' + l[0]
+ else :
+ arg = typemap[l[1]] + ' ' + l[0]
+ elif l[2] == 'out' :
+ arg = typemap[l[1]] + ' *' + l[0]
+
+ al.append(arg)
+
+ if len(al) == 0 :
+ arglist = 'void'
+ else:
+ arglist = ', '.join(al)
+
+ if wrappers[w]['category'].startswith('VERSION_1_0') or wrappers[w]['category'].startswith('VERSION_1_1') :
+ if staticwrappers :
+ print 'static',
+ print returntype + ' __stdcall ' + funcname + 'Wrapper(' + arglist + ')'
+ print '{'
+ print '#ifdef _DEBUG'
+ print ' //if (glxWinDebugSettings.enable' + prefix.upper() + 'callTrace) ErrorF("'+ funcname + '\\n");'
+ print ' glWinDirectProcCalls++;'
+ print '#endif'
+ if returntype.lower() == 'void' :
+ print ' ' + funcname + '(',
+ else :
+ print ' /* returntype was ' + returntype.lower() + '*/'
+ print ' return ' + funcname + '(',
+
+ if arglist != 'void' :
+ print wrappers[w]['arglist_use'],
+
+ print ');'
+ print "}\n"
+ else:
+ if staticwrappers :
+ print 'static',
+ print returntype + ' __stdcall ' + funcname + 'Wrapper(' + arglist + ')'
+ print '{'
+
+ stringname = funcname
+
+#
+# special case: Windows OpenGL implementations are far more likely to have GL_ARB_window_pos than GL_MESA_window_pos,
+# so arrange for the wrapper to use the ARB strings to find functions...
+#
+
+ m2 = r3.search(funcname)
+ if m2 :
+ stringname = stringname.replace('MESA','ARB')
+
+#
+# special case: likewise, implementations are more likely to have GL_ARB_vertex_program than GL_NV_vertex_program,
+# especially if they are not NV implementations, so arrange for the wrapper to use ARB strings to find functions
+#
+
+ m3 = r4.search(funcname)
+ if m3 :
+ stringname = stringname.replace('NV','ARB')
+ m4 = r5.search(funcname)
+ if m4 :
+ stringname = stringname.replace('NV','ARB')
+
+ pfntypename = 'PFN' + funcname.upper() + 'PROC'
+
+ if returntype.lower() == 'void' :
+ print ' RESOLVE(' + pfntypename + ', "' + stringname + '");'
+ print '#ifdef _DEBUG'
+ print ' //if (glxWinDebugSettings.enable' + prefix.upper() + 'callTrace) ErrorF("'+ funcname + '\\n");'
+ print '#endif'
+ print ' RESOLVED_PROC(' + pfntypename + ')(',
+ else :
+ print ' RESOLVE_RET(' + pfntypename + ', "' + stringname + '", FALSE);'
+ print '#ifdef _DEBUG'
+ print ' //if (glxWinDebugSettings.enable' + prefix.upper() + 'callTrace) ErrorF("'+ funcname + '\\n");'
+ print '#endif'
+ print ' return RESOLVED_PROC(' + pfntypename + ')(',
+
+ if arglist != 'void' :
+ print wrappers[w]['arglist_use'],
+
+ print ');'
+ print "}\n"
+
+
+# generate function to setup the dispatch table, which sets each
+# dispatch table entry to point to it's wrapper function
+# (assuming we were able to make one)
+
+if dispatchheader :
+ print 'void glWinSetupDispatchTable(void)'
+ print '{'
+ print ' struct _glapi_table *disp = _glapi_get_dispatch();'
+
+ for d in sorted(dispatch.keys()) :
+ if wrappers.has_key(d) :
+ print ' SET_'+ d + '(disp, (void *)' + prefix + d + 'Wrapper);'
+ else :
+ print '#pragma message("No wrapper for ' + prefix + d + ' !")'
+
+ print '}'