summaryrefslogtreecommitdiffstats
path: root/src/mesa/glapi/glX_proto_send.py
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2004-12-01 08:35:37 +0000
committerIan Romanick <[email protected]>2004-12-01 08:35:37 +0000
commite9789cf07186e710ee212effb2c25be96f7cbff2 (patch)
tree9ac6a826809100b80635d19e8cdd67776798d084 /src/mesa/glapi/glX_proto_send.py
parent6b89a8363b4934e4b5bbad10f84bbe7e38f22f9b (diff)
Python script to generate various bits of client-side GLX protocol code.
Diffstat (limited to 'src/mesa/glapi/glX_proto_send.py')
-rw-r--r--src/mesa/glapi/glX_proto_send.py981
1 files changed, 981 insertions, 0 deletions
diff --git a/src/mesa/glapi/glX_proto_send.py b/src/mesa/glapi/glX_proto_send.py
new file mode 100644
index 00000000000..77d54b6ef1e
--- /dev/null
+++ b/src/mesa/glapi/glX_proto_send.py
@@ -0,0 +1,981 @@
+#!/usr/bin/python2
+
+# (C) Copyright IBM Corporation 2004
+# 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 <[email protected]>
+
+from xml.sax import saxutils
+from xml.sax import make_parser
+from xml.sax.handler import feature_namespaces
+
+import gl_XML
+import license
+import sys, getopt
+
+
+def printPure():
+ print """# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
+# define PURE __attribute__((pure))
+# else
+# define PURE
+# endif"""
+
+def printFastcall():
+ print """# if defined(__i386__) && defined(__GNUC__)
+# define FASTCALL __attribute__((fastcall))
+# else
+# define FASTCALL
+# endif"""
+
+def printVisibility(S, s):
+ print """# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
+# define %s __attribute__((visibility("%s")))
+# else
+# define %s
+# endif""" % (S, s, S)
+
+def printNoinline():
+ print """# if defined(__GNUC__)
+# define NOINLINE __attribute__((noinline))
+# else
+# define NOINLINE
+# endif"""
+
+
+class glXItemFactory(gl_XML.glItemFactory):
+ """Factory to create GLX protocol oriented objects derived from glItem."""
+
+ def create(self, context, name, attrs):
+ if name == "function":
+ return glXFunction(context, name, attrs)
+ elif name == "enum":
+ return glXEnum(context, name, attrs)
+ elif name == "param":
+ return glXParameter(context, name, attrs)
+ else:
+ return gl_XML.glItemFactory.create(self, context, name, attrs)
+
+class glXEnumFunction:
+ def __init__(self, name):
+ self.name = name
+
+ # "enums" is a set of lists. The element in the set is the
+ # value of the enum. The list is the list of names for that
+ # value. For example, [0x8126] = {"POINT_SIZE_MIN",
+ # "POINT_SIZE_MIN_ARB", "POINT_SIZE_MIN_EXT",
+ # "POINT_SIZE_MIN_SGIS"}.
+
+ self.enums = {}
+
+ # "count" is indexed by count values. Each element of count
+ # is a list of index to "enums" that have that number of
+ # associated data elements. For example, [4] =
+ # {GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_EMISSION,
+ # GL_AMBIENT_AND_DIFFUSE} (the enum names are used here,
+ # but the actual hexadecimal values would be in the array).
+
+ self.count = {}
+
+
+ def append(self, count, value, name):
+ if self.enums.has_key( value ):
+ self.enums[value].append(name)
+ else:
+ if not self.count.has_key(count):
+ self.count[count] = []
+
+ self.enums[value] = []
+ self.enums[value].append(name)
+ self.count[count].append(value)
+
+
+ def signature( self ):
+ sig = ""
+ for i in self.count:
+ for e in self.count[i]:
+ sig += "%04x,%u," % (e, i)
+
+ return sig;
+
+
+ def PrintUsingTable(self):
+ """Emit the body of the __gl*_size function using a pair
+ of look-up tables and a mask. The mask is calculated such
+ that (e & mask) is unique for all the valid values of e for
+ this function. The result of (e & mask) is used as an index
+ into the first look-up table. If it matches e, then the
+ same entry of the second table is returned. Otherwise zero
+ is returned.
+
+ It seems like this should cause better code to be generated.
+ However, on x86 at least, the resulting .o file is about 20%
+ larger then the switch-statment version. I am leaving this
+ code in because the results may be different on other
+ platforms (e.g., PowerPC or x86-64)."""
+
+ return 0
+ count = 0
+ for a in self.enums:
+ count += 1
+
+ # Determine if there is some mask M, such that M = (2^N) - 1,
+ # that will generate unique values for all of the enums.
+
+ mask = 0
+ for i in [1, 2, 3, 4, 5, 6, 7, 8]:
+ mask = (1 << i) - 1
+
+ fail = 0;
+ for a in self.enums:
+ for b in self.enums:
+ if a != b:
+ if (a & mask) == (b & mask):
+ fail = 1;
+
+ if not fail:
+ break;
+ else:
+ mask = 0
+
+ if (mask != 0) and (mask < (2 * count)):
+ masked_enums = {}
+ masked_count = {}
+
+ for i in range(0, mask):
+ masked_enums[i] = "0";
+ masked_count[i] = 0;
+
+ for c in self.count:
+ for e in self.count[c]:
+ i = e & mask
+ masked_enums[i] = '0x%04x /* %s */' % (e, self.enums[e][0])
+ masked_count[i] = c
+
+
+ print ' static const GLushort a[%u] = {' % (mask + 1)
+ for e in masked_enums:
+ print ' %s, ' % (masked_enums[e])
+ print ' };'
+
+ print ' static const GLubyte b[%u] = {' % (mask + 1)
+ for c in masked_count:
+ print ' %u, ' % (masked_count[c])
+ print ' };'
+
+ print ' const unsigned idx = (e & 0x%02xU);' % (mask)
+ print ''
+ print ' return (e == a[idx]) ? (GLint) b[idx] : 0;'
+ return 1;
+ else:
+ return 0;
+
+ def PrintUsingSwitch(self):
+ """Emit the body of the __gl*_size function using a
+ switch-statement."""
+
+ print ' switch( e ) {'
+
+ for c in self.count:
+ for e in self.count[c]:
+ first = 1
+
+ # There may be multiple enums with the same
+ # value. This happens has extensions are
+ # promoted from vendor-specific or EXT to
+ # ARB and to the core. Emit the first one as
+ # a case label, and emit the others as
+ # commented-out case labels.
+
+ for j in self.enums[e]:
+ if first:
+ print ' case %s:' % (j)
+ first = 0
+ else:
+ print '/* case %s:*/' % (j)
+
+ print ' return %u;' % (c)
+
+ print ' default: return 0;'
+ print ' }'
+
+
+ def Print(self, name):
+ print 'INTERNAL PURE FASTCALL GLint'
+ print '__gl%s_size( GLenum e )' % (name)
+ print '{'
+
+ if not self.PrintUsingTable():
+ self.PrintUsingSwitch()
+
+ print '}'
+ print ''
+
+
+
+class glXEnum(gl_XML.glEnum):
+ def __init__(self, context, name, attrs):
+ gl_XML.glEnum.__init__(self, context, name, attrs)
+ self.glx_functions = []
+
+ def startElement(self, name, attrs):
+ if name == "size":
+ n = attrs.get('name', None)
+ if not self.context.glx_enum_functions.has_key( n ):
+ f = glXEnumFunction( n )
+ self.context.glx_enum_functions[ f.name ] = f
+
+ temp = attrs.get('count', None)
+ try:
+ c = int(temp)
+ except Exception,e:
+ raise RuntimeError('Invalid count value "%s" for enum "%s" in function "%s" when an integer was expected.' % (temp, self.name, n))
+
+ self.context.glx_enum_functions[ n ].append( c, self.value, self.name )
+ else:
+ gl_XML.glEnum.startElement(self, context, name, attrs)
+ return
+
+
+class glXParameter(gl_XML.glParameter):
+ def __init__(self, context, name, attrs):
+ self.order = 1;
+ gl_XML.glParameter.__init__(self, context, name, attrs);
+
+
+class glXFunction(gl_XML.glFunction):
+ glx_rop = 0
+ glx_sop = 0
+ glx_vendorpriv = 0
+
+ # If this is set to true, it means that GLdouble parameters should be
+ # written to the GLX protocol packet in the order they appear in the
+ # prototype. This is different from the "classic" ordering. In the
+ # classic ordering GLdoubles are written to the protocol packet first,
+ # followed by non-doubles. NV_vertex_program was the first extension
+ # to break with this tradition.
+
+ glx_doubles_in_order = 0
+
+ vectorequiv = None
+ handcode = 0
+ ignore = 0
+ can_be_large = 0
+
+ def __init__(self, context, name, attrs):
+ self.vectorequiv = attrs.get('vectorequiv', None)
+ self.count_parameters = None
+ self.counter = None
+ self.output = None
+ self.can_be_large = 0
+ self.reply_always_array = 0
+
+ gl_XML.glFunction.__init__(self, context, name, attrs)
+ return
+
+ def startElement(self, name, attrs):
+ """Process elements within a function that are specific to GLX."""
+
+ if name == "glx":
+ self.glx_rop = int(attrs.get('rop', "0"))
+ self.glx_sop = int(attrs.get('sop', "0"))
+ self.glx_vendorpriv = int(attrs.get('vendorpriv', "0"))
+
+ if attrs.get('handcode', "false") == "true":
+ self.handcode = 1
+ else:
+ self.handcode = 0
+
+ if attrs.get('ignore', "false") == "true":
+ self.ignore = 1
+ else:
+ self.ignore = 0
+
+ if attrs.get('large', "false") == "true":
+ self.can_be_large = 1
+ else:
+ self.can_be_large = 0
+
+ if attrs.get('doubles_in_order', "false") == "true":
+ self.glx_doubles_in_order = 1
+ else:
+ self.glx_doubles_in_order = 0
+
+ if attrs.get('always_array', "false") == "true":
+ self.reply_always_array = 1
+ else:
+ self.reply_always_array = 0
+
+ else:
+ gl_XML.glFunction.startElement(self, name, attrs)
+
+
+ def append(self, tag_name, p):
+ gl_XML.glFunction.append(self, tag_name, p)
+
+ if p.is_variable_length_array():
+ p.order = 2;
+ elif not self.glx_doubles_in_order and p.p_type.size == 8:
+ p.order = 0;
+
+ if p.p_count_parameters != None:
+ self.count_parameters = p.p_count_parameters
+
+ if p.is_counter:
+ self.counter = p.name
+
+ if p.is_output:
+ self.output = p
+
+ return
+
+ def variable_length_parameter(self):
+ for param in self.fn_parameters:
+ if param.is_variable_length_array():
+ return param
+
+ return None
+
+
+ def command_payload_length(self):
+ size = 0
+ size_string = ""
+ for p in self:
+ if p.is_output: continue
+ temp = p.size_string()
+ try:
+ s = int(temp)
+ size += s
+ except Exception,e:
+ size_string = size_string + " + __GLX_PAD(%s)" % (temp)
+
+ return [size, size_string]
+
+ def command_length(self):
+ [size, size_string] = self.command_payload_length()
+
+ if self.glx_rop != 0:
+ size += 4
+
+ size = ((size + 3) & ~3)
+ return "%u%s" % (size, size_string)
+
+
+ def opcode_value(self):
+ if self.glx_rop != 0:
+ return self.glx_rop
+ elif self.glx_sop != 0:
+ return self.glx_sop
+ elif self.glx_vendorpriv != 0:
+ return self.glx_vendorpriv
+ else:
+ return -1
+
+ def opcode_rop_basename(self):
+ if self.vectorequiv == None:
+ return self.name
+ else:
+ return self.vectorequiv
+
+ def opcode_name(self):
+ if self.glx_rop != 0:
+ return "X_GLrop_%s" % (self.opcode_rop_basename())
+ elif self.glx_sop != 0:
+ return "X_GLsop_%s" % (self.name)
+ elif self.glx_vendorpriv != 0:
+ return "X_GLvop_%s" % (self.name)
+ else:
+ return "ERROR"
+
+ def opcode_real_name(self):
+ if self.glx_vendorpriv != 0:
+ if self.needs_reply():
+ return "X_GLXVendorPrivateWithReply"
+ else:
+ return "X_GLXVendorPrivate"
+ else:
+ return self.opcode_name()
+
+
+ def return_string(self):
+ if self.fn_return_type != 'void':
+ return "return retval;"
+ else:
+ return "return;"
+
+
+ def needs_reply(self):
+ return self.fn_return_type != 'void' or self.output != None
+
+
+class GlxProto(gl_XML.FilterGLAPISpecBase):
+ name = "glX_proto_send.py (from Mesa)"
+
+ def __init__(self):
+ gl_XML.FilterGLAPISpecBase.__init__(self)
+ self.factory = glXItemFactory()
+ self.glx_enum_functions = {}
+
+
+ def endElement(self, name):
+ if name == 'OpenGLAPI':
+ # Once all the parsing is done, we have to go back and
+ # fix-up some cross references between different
+ # functions.
+
+ for k in self.functions:
+ f = self.functions[k]
+ if f.vectorequiv != None:
+ equiv = self.find_function(f.vectorequiv)
+ if equiv != None:
+ f.glx_doubles_in_order = equiv.glx_doubles_in_order
+ f.glx_rop = equiv.glx_rop
+ else:
+ raise RuntimeError("Could not find the vector equiv. function %s for %s!" % (f.name, f.vectorequiv))
+ else:
+ gl_XML.FilterGLAPISpecBase.endElement(self, name)
+ return
+
+
+class PrintGlxProtoStubs(GlxProto):
+ def __init__(self):
+ GlxProto.__init__(self)
+ self.last_category = ""
+ self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004", "IBM")
+ self.generic_sizes = [3, 4, 6, 8, 12, 16, 24, 32]
+ return
+
+ def printRealHeader(self):
+ print ''
+ print '#include <GL/gl.h>'
+ print '#include "indirect.h"'
+ print '#include "glxclient.h"'
+ print '#include "size.h"'
+ print '#include <GL/glxproto.h>'
+ print ''
+ print '#define __GLX_PAD(n) (((n) + 3) & ~3)'
+ print ''
+ printFastcall()
+ printNoinline()
+ print ''
+ print '/* If the size and opcode values are known at compile-time, this will, on'
+ print ' * x86 at least, emit them with a single instruction.'
+ print ' */'
+ print '#define emit_header(dest, op, size) \\'
+ print ' do { union { short s[2]; int i; } temp; \\'
+ print ' temp.s[0] = (size); temp.s[1] = (op); \\'
+ print ' *((int *)(dest)) = temp.i; } while(0)'
+ print ''
+ print """static NOINLINE CARD32
+read_reply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array )
+{
+ xGLXSingleReply reply;
+
+ (void) _XReply(dpy, (xReply *) & reply, 0, False);
+ if (size != 0) {
+ if ((reply.size >= 1) || reply_is_always_array) {
+ const GLint bytes = (reply_is_always_array)
+ ? (4 * reply.length) : (reply.size * size);
+ const GLint extra = 4 - (bytes & 3);
+
+ _XRead(dpy, dest, bytes);
+ if ( extra != 0 ) {
+ _XEatData(dpy, extra);
+ }
+ }
+ else {
+ (void) memcpy( dest, &(reply.pad3), size);
+ }
+ }
+
+ return reply.retval;
+}
+
+#define X_GLXSingle 0
+
+static NOINLINE GLubyte *
+setup_single_request( __GLXcontext * gc, GLint sop, GLint cmdlen )
+{
+ xGLXSingleReq * req;
+ Display * const dpy = gc->currentDpy;
+
+ (void) __glXFlushRenderBuffer(gc, gc->pc);
+ LockDisplay(dpy);
+ GetReqExtra(GLXSingle, cmdlen, req);
+ req->reqType = gc->majorOpcode;
+ req->contextTag = gc->currentContextTag;
+ req->glxCode = sop;
+ return (GLubyte *)(req) + sz_xGLXSingleReq;
+}
+
+static NOINLINE GLubyte *
+setup_vendor_request( __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen )
+{
+ xGLXVendorPrivateReq * req;
+ Display * const dpy = gc->currentDpy;
+
+ (void) __glXFlushRenderBuffer(gc, gc->pc);
+ LockDisplay(dpy);
+ GetReqExtra(GLXVendorPrivate, cmdlen, req);
+ req->reqType = gc->majorOpcode;
+ req->glxCode = code;
+ req->vendorCode = vop;
+ req->contextTag = gc->currentContextTag;
+ return (GLubyte *)(req) + sz_xGLXVendorPrivateReq;
+}
+"""
+
+ for size in self.generic_sizes:
+ self.print_generic_function(size)
+ return
+
+ def printFunction(self, f):
+ if f.fn_offset < 0 or f.handcode or f.ignore: return
+
+ if f.glx_rop != 0 or f.vectorequiv != None:
+ self.printRenderFunction(f)
+ elif f.glx_sop != 0 or f.glx_vendorpriv != 0:
+ self.printSingleFunction(f)
+ else:
+ print "/* Missing GLX protocol for %s. */" % (f.name)
+
+ def print_generic_function(self, n):
+ print """static FASTCALL NOINLINE void
+generic_%u_byte( GLint rop, const void * ptr )
+{
+ __GLXcontext * const gc = __glXGetCurrentContext();
+ const GLuint cmdlen = %u;
+
+ emit_header(gc->pc, rop, cmdlen);
+ (void) memcpy((void *)(gc->pc + 4), ptr, %u);
+ gc->pc += cmdlen;
+ if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }
+}
+""" % (n, n + 4, n)
+
+
+ def common_emit_one_arg(self, p, offset, pc, indent, adjust):
+ if p.is_output: return
+
+ t = p.p_type
+ if p.is_array():
+ src_ptr = p.name
+ else:
+ src_ptr = "&" + p.name
+
+ print '%s (void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
+ % (indent, pc, offset + adjust, src_ptr, p.size_string() )
+
+ def common_emit_args(self, f, pc, indent, adjust, skip_vla):
+ # First emit all of the fixed-length 8-byte (i.e., GLdouble)
+ # parameters.
+
+ offset = 0
+
+ if skip_vla:
+ r = [0, 1]
+ else:
+ r = [0, 1, 2]
+
+ for order in r:
+ for p in f:
+ if p.is_output or p.order != order: continue
+
+ self.common_emit_one_arg(p, offset, pc, indent, adjust)
+ offset += p.size()
+
+
+ return offset
+
+
+ def common_func_print_just_header(self, f):
+ print '#define %s %d' % (f.opcode_name(), f.opcode_value())
+
+ print '%s' % (f.fn_return_type)
+ print '__indirect_gl%s(%s)' % (f.name, f.get_parameter_string())
+ print '{'
+
+
+ def common_func_print_header(self, f):
+ self.common_func_print_just_header(f)
+
+ print ' __GLXcontext * const gc = __glXGetCurrentContext();'
+ print ' Display * const dpy = gc->currentDpy;'
+
+ if f.fn_return_type != 'void':
+ print ' %s retval = (%s) 0;' % (f.fn_return_type, f.fn_return_type)
+
+ if f.count_parameters != None:
+ print ' const GLuint compsize = __gl%s_size(%s);' % (f.name, f.count_parameters)
+
+ print ' const GLuint cmdlen = %s;' % (f.command_length())
+
+ if f.counter != None:
+ print ' if (%s < 0) %s' % (f.counter, f.return_string())
+
+ if f.can_be_large:
+ print ' if (dpy == NULL) return;'
+ print ' if ( ((gc->pc + cmdlen) > gc->bufEnd)'
+ print ' || (cmdlen > gc->maxSmallRenderCommandSize)) {'
+ print ' (void) __glXFlushRenderBuffer(gc, gc->pc);'
+ print ' }'
+ else:
+ print ' (void) dpy;'
+
+ return
+
+
+ def printSingleFunction(self, f):
+ self.common_func_print_header(f)
+
+ print ' if (dpy != NULL) {'
+
+ if f.fn_parameters != []:
+ pc_decl = "GLubyte const * pc ="
+ else:
+ pc_decl = "(void)"
+
+ if f.glx_vendorpriv != 0:
+ print ' %s setup_vendor_request(gc, %s, %s, cmdlen);' % (pc_decl, f.opcode_real_name(), f.opcode_name())
+ else:
+ print ' %s setup_single_request(gc, %s, cmdlen);' % (pc_decl, f.opcode_name())
+
+ self.common_emit_args(f, "pc", " ", 0, 0)
+
+ if f.needs_reply():
+ if f.output != None:
+ output_size = f.output.p_type.size
+ output_str = f.output.name
+ else:
+ output_size = 0
+ output_str = "NULL"
+
+ if f.fn_return_type != 'void':
+ return_str = " retval = (%s)" % (f.fn_return_type)
+ else:
+ return_str = " (void)"
+
+ if f.reply_always_array:
+ aa = "GL_TRUE"
+ else:
+ aa = "GL_FALSE"
+
+ print " %s read_reply(gc->currentDpy, %s, %s, %s);" % (return_str, output_size, output_str, aa)
+
+ print ' UnlockDisplay(gc->currentDpy); SyncHandle();'
+ print ' }'
+ print ' %s' % f.return_string()
+ print '}'
+ print ''
+ return
+
+
+ def printRenderFunction(self, f):
+ if f.variable_length_parameter() == None and len(f.fn_parameters) == 1:
+ p = f.fn_parameters[0]
+ if p.is_pointer:
+ [cmdlen, size_string] = f.command_payload_length()
+ if cmdlen in self.generic_sizes:
+ self.common_func_print_just_header(f)
+ print ' generic_%u_byte( %s, %s );' % (cmdlen, f.opcode_real_name(), p.name)
+ print '}'
+ print ''
+ return
+
+ self.common_func_print_header(f)
+
+ if f.can_be_large:
+ print ' if (cmdlen <= gc->maxSmallRenderCommandSize) {'
+ indent = " "
+ else:
+ indent = ""
+
+ print '%s emit_header(gc->pc, %s, cmdlen);' % (indent, f.opcode_real_name())
+
+ self.common_emit_args(f, "gc->pc", indent, 4, 0)
+ print '%s gc->pc += cmdlen;' % (indent)
+ print '%s if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent)
+
+ if f.can_be_large:
+ print ' }'
+ print ' else {'
+ print ' const GLint op = %s;' % (f.opcode_real_name())
+ print ' const GLuint cmdlenLarge = cmdlen + 4;'
+ print ' (void) memcpy((void *)(gc->pc + 0), (void *)(&op), 4);'
+ print ' (void) memcpy((void *)(gc->pc + 4), (void *)(&cmdlenLarge), 4);'
+ offset = self.common_emit_args(f, "gc->pc", indent, 8, 1)
+
+ p = f.variable_length_parameter()
+ print ' __glXSendLargeCommand(gc, gc->pc, %u, %s, %s);' % (offset + 8, p.name, p.size_string())
+ print ' }'
+
+ print '}'
+ print ''
+ return
+
+
+class PrintGlxProtoInit_c(GlxProto):
+ def __init__(self):
+ GlxProto.__init__(self)
+ self.last_category = ""
+ self.license = license.bsd_license_template % ( \
+"""Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+(C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
+
+
+ def printRealHeader(self):
+ print """/**
+ * \\file indirect_init.c
+ * Initialize indirect rendering dispatch table.
+ *
+ * \\author Kevin E. Martin <[email protected]>
+ * \\author Brian Paul <[email protected]>
+ * \\author Ian Romanick <[email protected]>
+ */
+
+#include "indirect_init.h"
+#include "indirect.h"
+#include "glapi.h"
+
+
+/**
+ * No-op function used to initialize functions that have no GLX protocol
+ * support.
+ */
+static int NoOp(void)
+{
+ return 0;
+}
+
+/**
+ * Create and initialize a new GL dispatch table. The table is initialized
+ * with GLX indirect rendering protocol functions.
+ */
+__GLapi * __glXNewIndirectAPI( void )
+{
+ __GLapi *glAPI;
+ GLuint entries;
+
+ entries = _glapi_get_dispatch_table_size();
+ glAPI = (__GLapi *) Xmalloc(entries * sizeof(void *));
+
+ /* first, set all entries to point to no-op functions */
+ {
+ int i;
+ void **dispatch = (void **) glAPI;
+ for (i = 0; i < entries; i++) {
+ dispatch[i] = (void *) NoOp;
+ }
+ }
+
+ /* now, initialize the entries we understand */"""
+
+ def printRealFooter(self):
+ print """
+ return glAPI;
+}
+"""
+
+ def printFunction(self, f):
+ if f.fn_offset < 0 or f.ignore: return
+
+ if f.category != self.last_category:
+ self.last_category = f.category
+ print ''
+ print ' /* %s */' % (self.last_category)
+ print ''
+
+ print ' glAPI->%s = __indirect_gl%s;' % (f.name, f.name)
+
+
+class PrintGlxProtoInit_h(GlxProto):
+ def __init__(self):
+ GlxProto.__init__(self)
+ self.last_category = ""
+ self.license = license.bsd_license_template % ( \
+"""Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+(C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
+
+
+ def printRealHeader(self):
+ print """
+/**
+ * \\file
+ * Prototypes for indirect rendering functions.
+ *
+ * \\author Kevin E. Martin <[email protected]>
+ * \\author Ian Romanick <[email protected]>
+ */
+
+#if !defined( _INDIRECT_H_ )
+# define _INDIRECT_H_
+
+"""
+ printVisibility( "HIDDEN", "hidden" )
+
+
+ def printRealFooter(self):
+ print "# undef HIDDEN"
+ print "#endif /* !defined( _INDIRECT_H_ ) */"
+
+ def printFunction(self, f):
+ if f.fn_offset < 0 or f.ignore: return
+ print 'extern HIDDEN %s __indirect_gl%s(%s);' % (f.fn_return_type, f.name, f.get_parameter_string())
+
+
+class PrintGlxSizeStubs(GlxProto):
+ def __init__(self):
+ GlxProto.__init__(self)
+ self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004", "IBM")
+ self.aliases = []
+ self.glx_enum_sigs = {}
+
+ def printRealHeader(self):
+ print ''
+ print '#include <GL/gl.h>'
+ print '#include "indirect_size.h"'
+
+ print ''
+ printPure()
+ print ''
+ printFastcall()
+ print ''
+ printVisibility( "INTERNAL", "internal" )
+ print ''
+ print ''
+ print '#ifdef HAVE_ALIAS'
+ print '# define ALIAS2(from,to) \\'
+ print ' INTERNAL PURE FASTCALL GLint __gl ## from ## _size( GLenum e ) \\'
+ print ' __attribute__ ((alias( # to )));'
+ print '# define ALIAS(from,to) ALIAS2( from, __gl ## to ## _size )'
+ print '#else'
+ print '# define ALIAS(from,to) \\'
+ print ' INTERNAL PURE FASTCALL GLint __gl ## from ## _size( GLenum e ) \\'
+ print ' { return __gl ## to ## _size( e ); }'
+ print '#endif'
+ print ''
+ print ''
+
+ def printRealFooter(self):
+ for a in self.aliases:
+ print a
+
+ def printFunction(self, f):
+ if self.glx_enum_functions.has_key(f.name):
+ ef = self.glx_enum_functions[f.name]
+
+ sig = ef.signature();
+ if self.glx_enum_sigs.has_key(sig):
+ n = self.glx_enum_sigs[sig];
+ a = 'ALIAS( %s, %s )' % (f.name, n)
+ self.aliases.append(a)
+ else:
+ ef.Print( f.name )
+ self.glx_enum_sigs[sig] = f.name;
+
+
+
+class PrintGlxSizeStubs_h(GlxProto):
+ def __init__(self):
+ GlxProto.__init__(self)
+ self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004", "IBM")
+ self.aliases = []
+ self.glx_enum_sigs = {}
+
+ def printRealHeader(self):
+ print """
+/**
+ * \\file
+ * Prototypes for functions used to determine the number of data elements in
+ * various GLX protocol messages.
+ *
+ * \\author Ian Romanick <[email protected]>
+ */
+
+#if !defined( _GLXSIZE_H_ )
+# define _GLXSIZE_H_
+
+"""
+ printPure();
+ print ''
+ printFastcall();
+ print ''
+ printVisibility( "INTERNAL", "internal" );
+ print ''
+
+ def printRealFooter(self):
+ print ''
+ print "# undef INTERNAL"
+ print "# undef PURE"
+ print "# undef FASTCALL"
+ print "#endif /* !defined( _GLXSIZE_H_ ) */"
+
+
+ def printFunction(self, f):
+ if self.glx_enum_functions.has_key(f.name):
+ ef = self.glx_enum_functions[f.name]
+ print 'extern INTERNAL GLint __gl%s_size(GLenum) PURE FASTCALL;' % (f.name)
+
+
+def show_usage():
+ print "Usage: %s [-f input_file_name] [-m output_mode]" % sys.argv[0]
+ sys.exit(1)
+
+
+if __name__ == '__main__':
+ file_name = "gl_API.xml"
+
+ try:
+ (args, trail) = getopt.getopt(sys.argv[1:], "f:m:")
+ except Exception,e:
+ show_usage()
+
+ mode = "proto"
+ for (arg,val) in args:
+ if arg == "-f":
+ file_name = val
+ elif arg == "-m":
+ mode = val
+
+ if mode == "proto":
+ dh = PrintGlxProtoStubs()
+ elif mode == "init_c":
+ dh = PrintGlxProtoInit_c()
+ elif mode == "init_h":
+ dh = PrintGlxProtoInit_h()
+ elif mode == "size_c":
+ dh = PrintGlxSizeStubs()
+ elif mode == "size_h":
+ dh = PrintGlxSizeStubs_h()
+ else:
+ show_usage()
+
+ parser = make_parser()
+ parser.setFeature(feature_namespaces, 0)
+ parser.setContentHandler(dh)
+
+ f = open(file_name)
+
+ dh.printHeader()
+ parser.parse(f)
+ dh.printFooter()