glx: Remove unused indirection for glx_context->fillImage
[mesa.git] / src / mapi / glapi / gen / glX_proto_send.py
index bd41c9e667ac8dabdb7587f650d1ddc6b6c493e4..a269ff2068d412c9190dee6993e067d37fd556c7 100644 (file)
@@ -1,7 +1,7 @@
-#!/usr/bin/env python
 
 # (C) Copyright IBM Corporation 2004, 2005
 # All Rights Reserved.
+# Copyright (c) 2015 Intel Corporation
 #
 # Permission is hereby granted, free of charge, to any person obtaining a
 # copy of this software and associated documentation files (the "Software"),
 #    Ian Romanick <idr@us.ibm.com>
 #    Jeremy Kolb <jkolb@brandeis.edu>
 
+from __future__ import division, print_function
+
+import argparse
+
 import gl_XML, glX_XML, glX_proto_common, license
-import sys, getopt, copy, string
+import copy
 
 def convertStringForXCB(str):
     tmp = ""
@@ -35,166 +39,184 @@ def convertStringForXCB(str):
     i = 0
     while i < len(str):
         if str[i:i+3] in special:
-            tmp = '%s_%s' % (tmp, string.lower(str[i:i+3]))
+            tmp = '%s_%s' % (tmp, str[i:i+3].lower())
             i = i + 2;
         elif str[i].isupper():
-            tmp = '%s_%s' % (tmp, string.lower(str[i]))
+            tmp = '%s_%s' % (tmp, str[i].lower())
         else:
             tmp = '%s%s' % (tmp, str[i])
         i += 1
     return tmp
 
 def hash_pixel_function(func):
-       """Generate a 'unique' key for a pixel function.  The key is based on
-       the parameters written in the command packet.  This includes any
-       padding that might be added for the original function and the 'NULL
-       image' flag."""
+    """Generate a 'unique' key for a pixel function.  The key is based on
+    the parameters written in the command packet.  This includes any
+    padding that might be added for the original function and the 'NULL
+    image' flag."""
 
 
-       h = ""
-       hash_pre = ""
-       hash_suf = ""
-       for param in func.parameterIterateGlxSend():
-               if param.is_image():
-                       [dim, junk, junk, junk, junk] = param.get_dimensions()
+    h = ""
+    hash_pre = ""
+    hash_suf = ""
+    for param in func.parameterIterateGlxSend():
+        if param.is_image():
+            [dim, junk, junk, junk, junk] = param.get_dimensions()
 
-                       d = (dim + 1) & ~1
-                       hash_pre = "%uD%uD_" % (d - 1, d)
+            d = (dim + 1) & ~1
+            hash_pre = "%uD%uD_" % (d - 1, d)
 
-                       if param.img_null_flag:
-                               hash_suf = "_NF"
+            if param.img_null_flag:
+                hash_suf = "_NF"
 
-               h += "%u" % (param.size())
+        h += "%u" % (param.size())
 
-               if func.pad_after(param):
-                       h += "4"
+        if func.pad_after(param):
+            h += "4"
 
 
-       n = func.name.replace("%uD" % (dim), "")
-       n = "__glx_%s_%uD%uD" % (n, d - 1, d)
+    n = func.name.replace("%uD" % (dim), "")
+    n = "__glx_%s_%uD%uD" % (n, d - 1, d)
 
-       h = hash_pre + h + hash_suf
-       return [h, n]
+    h = hash_pre + h + hash_suf
+    return [h, n]
 
 
 class glx_pixel_function_stub(glX_XML.glx_function):
-       """Dummy class used to generate pixel "utility" functions that are
-       shared by multiple dimension image functions.  For example, these
-       objects are used to generate shared functions used to send GLX
-       protocol for TexImage1D and TexImage2D, TexSubImage1D and
-       TexSubImage2D, etc."""
+    """Dummy class used to generate pixel "utility" functions that are
+    shared by multiple dimension image functions.  For example, these
+    objects are used to generate shared functions used to send GLX
+    protocol for TexImage1D and TexImage2D, TexSubImage1D and
+    TexSubImage2D, etc."""
+
+    def __init__(self, func, name):
+        # The parameters to the utility function are the same as the
+        # parameters to the real function except for the added "pad"
+        # parameters.
 
-       def __init__(self, func, name):
-               # The parameters to the utility function are the same as the
-               # parameters to the real function except for the added "pad"
-               # parameters.
+        self.name = name
+        self.images = []
+        self.parameters = []
+        self.parameters_by_name = {}
+        for _p in func.parameterIterator():
+            p = copy.copy(_p)
+            self.parameters.append(p)
+            self.parameters_by_name[ p.name ] = p
 
-               self.name = name
-               self.images = []
-               self.parameters = []
-               self.parameters_by_name = {}
-               for _p in func.parameterIterator():
-                       p = copy.copy(_p)
-                       self.parameters.append(p)
-                       self.parameters_by_name[ p.name ] = p
 
+            if p.is_image():
+                self.images.append(p)
+                p.height = "height"
 
-                       if p.is_image():
-                               self.images.append(p)
-                               p.height = "height"
+                if p.img_yoff == None:
+                    p.img_yoff = "yoffset"
 
-                               if p.img_yoff == None:
-                                       p.img_yoff = "yoffset"
+                if p.depth:
+                    if p.extent == None:
+                        p.extent = "extent"
 
-                               if p.depth:
-                                       if p.extent == None:
-                                               p.extent = "extent"
+                    if p.img_woff == None:
+                        p.img_woff = "woffset"
 
-                                       if p.img_woff == None:
-                                               p.img_woff = "woffset"
 
+            pad_name = func.pad_after(p)
+            if pad_name:
+                pad = copy.copy(p)
+                pad.name = pad_name
+                self.parameters.append(pad)
+                self.parameters_by_name[ pad.name ] = pad
 
-                       pad_name = func.pad_after(p)
-                       if pad_name:
-                               pad = copy.copy(p)
-                               pad.name = pad_name
-                               self.parameters.append(pad)
-                               self.parameters_by_name[ pad.name ] = pad
-                               
 
-               self.return_type = func.return_type
+        self.return_type = func.return_type
 
-               self.glx_rop = ~0
-               self.glx_sop = 0
-               self.glx_vendorpriv = 0
+        self.glx_rop = ~0
+        self.glx_sop = 0
+        self.glx_vendorpriv = 0
 
-               self.glx_doubles_in_order = func.glx_doubles_in_order
+        self.glx_doubles_in_order = func.glx_doubles_in_order
 
-               self.vectorequiv = None
-               self.output = None
-               self.can_be_large = func.can_be_large
-               self.reply_always_array = func.reply_always_array
-               self.dimensions_in_reply = func.dimensions_in_reply
-               self.img_reset = None
+        self.vectorequiv = None
+        self.output = None
+        self.can_be_large = func.can_be_large
+        self.reply_always_array = func.reply_always_array
+        self.dimensions_in_reply = func.dimensions_in_reply
+        self.img_reset = None
 
-               self.server_handcode = 0
-               self.client_handcode = 0
-               self.ignore = 0
+        self.server_handcode = 0
+        self.client_handcode = 0
+        self.ignore = 0
 
-               self.count_parameter_list = func.count_parameter_list
-               self.counter_list = func.counter_list
-               self.offsets_calculated = 0
-               return
+        self.count_parameter_list = func.count_parameter_list
+        self.counter_list = func.counter_list
+        self.offsets_calculated = 0
+        return
 
 
 class PrintGlxProtoStubs(glX_proto_common.glx_print_proto):
-       def __init__(self):
-               glX_proto_common.glx_print_proto.__init__(self)
-               self.name = "glX_proto_send.py (from Mesa)"
-               self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004, 2005", "IBM")
-
-
-               self.last_category = ""
-               self.generic_sizes = [3, 4, 6, 8, 12, 16, 24, 32]
-               self.pixel_stubs = {}
-               self.debug = 0
-               return
-
-       def printRealHeader(self):
-               print ''
-               print '#include <GL/gl.h>'
-               print '#include "indirect.h"'
-               print '#include "glxclient.h"'
-               print '#include "indirect_size.h"'
-               print '#include "glapidispatch.h"'
-               print '#include "glapi.h"'
-               print '#include "glthread.h"'
-               print '#include <GL/glxproto.h>'
-               print '#ifdef USE_XCB'
-               print '#include <X11/Xlib-xcb.h>'
-               print '#include <xcb/xcb.h>'
-               print '#include <xcb/glx.h>'
-               print '#endif /* USE_XCB */'
-
-               print ''
-               print '#define __GLX_PAD(n) (((n) + 3) & ~3)'
-               print ''
-               self.printFastcall()
-               self.printNoinline()
-               print ''
-               print '#ifndef __GNUC__'
-               print '#  define __builtin_expect(x, y) x'
-               print '#endif'
-               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 """NOINLINE CARD32
+    def __init__(self):
+        glX_proto_common.glx_print_proto.__init__(self)
+        self.name = "glX_proto_send.py (from Mesa)"
+        self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004, 2005", "IBM")
+
+
+        self.last_category = ""
+        self.generic_sizes = [3, 4, 6, 8, 12, 16, 24, 32]
+        self.pixel_stubs = {}
+        self.debug = 0
+        return
+
+    def printRealHeader(self):
+        print('')
+        print('#include <GL/gl.h>')
+        print('#include "indirect.h"')
+        print('#include "glxclient.h"')
+        print('#include "indirect_size.h"')
+        print('#include "glapi.h"')
+        print('#include <GL/glxproto.h>')
+        print('#include <X11/Xlib-xcb.h>')
+        print('#include <xcb/xcb.h>')
+        print('#include <xcb/glx.h>')
+        print('#include <limits.h>')
+
+        print('')
+        self.printFastcall()
+        self.printNoinline()
+        print('')
+
+        print('static _X_INLINE int safe_add(int a, int b)')
+        print('{')
+        print('    if (a < 0 || b < 0) return -1;')
+        print('    if (INT_MAX - a < b) return -1;')
+        print('    return a + b;')
+        print('}')
+        print('static _X_INLINE int safe_mul(int a, int b)')
+        print('{')
+        print('    if (a < 0 || b < 0) return -1;')
+        print('    if (a == 0 || b == 0) return 0;')
+        print('    if (a > INT_MAX / b) return -1;')
+        print('    return a * b;')
+        print('}')
+        print('static _X_INLINE int safe_pad(int a)')
+        print('{')
+        print('    int ret;')
+        print('    if (a < 0) return -1;')
+        print('    if ((ret = safe_add(a, 3)) < 0) return -1;')
+        print('    return ret & (GLuint)~3;')
+        print('}')
+        print('')
+
+        print('#ifndef __GNUC__')
+        print('#  define __builtin_expect(x, y) x')
+        print('#endif')
+        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("""NOINLINE CARD32
 __glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array )
 {
     xGLXSingleReply reply;
@@ -240,7 +262,7 @@ __glXReadPixelReply( Display *dpy, struct glx_context * gc, unsigned max_dim,
 
     size = reply.length * 4;
     if (size != 0) {
-        void * buf = Xmalloc( size );
+        void * buf = malloc( size );
 
         if ( buf == NULL ) {
             _XEatData(dpy, size);
@@ -256,7 +278,7 @@ __glXReadPixelReply( Display *dpy, struct glx_context * gc, unsigned max_dim,
 
             __glEmptyImage(gc, 3, width, height, depth, format, type,
                            buf, dest);
-            Xfree(buf);
+            free(buf);
         }
     }
 }
@@ -306,106 +328,157 @@ const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 };
 #define default_pixel_store_3D_size 36
 #define default_pixel_store_4D      (__glXDefaultPixelStore+0)
 #define default_pixel_store_4D_size 36
-"""
+""")
 
-               for size in self.generic_sizes:
-                       self.print_generic_function(size)
-               return
+        for size in self.generic_sizes:
+            self.print_generic_function(size)
+        return
 
 
-       def printBody(self, api):
+    def printBody(self, api):
 
-               self.pixel_stubs = {}
-               generated_stubs = []
+        self.pixel_stubs = {}
+        generated_stubs = []
 
-               for func in api.functionIterateGlx():
-                       if func.client_handcode: continue
+        for func in api.functionIterateGlx():
+            if func.client_handcode: continue
 
-                       # If the function is a pixel function with a certain
-                       # GLX protocol signature, create a fake stub function
-                       # for it.  For example, create a single stub function
-                       # that is used to implement both glTexImage1D and
-                       # glTexImage2D.
+            # If the function is a pixel function with a certain
+            # GLX protocol signature, create a fake stub function
+            # for it.  For example, create a single stub function
+            # that is used to implement both glTexImage1D and
+            # glTexImage2D.
 
-                       if func.glx_rop != 0:
-                               do_it = 0
-                               for image in func.get_images():
-                                       if image.img_pad_dimensions:
-                                               do_it = 1
-                                               break
+            if func.glx_rop != 0:
+                do_it = 0
+                for image in func.get_images():
+                    if image.img_pad_dimensions:
+                        do_it = 1
+                        break
 
 
-                               if do_it:
-                                       [h, n] = hash_pixel_function(func)
+                if do_it:
+                    [h, n] = hash_pixel_function(func)
 
 
-                                       self.pixel_stubs[ func.name ] = n
-                                       if h not in generated_stubs:
-                                               generated_stubs.append(h)
+                    self.pixel_stubs[ func.name ] = n
+                    if h not in generated_stubs:
+                        generated_stubs.append(h)
 
-                                               fake_func = glx_pixel_function_stub( func, n )
-                                               self.printFunction(fake_func, fake_func.name)
+                        fake_func = glx_pixel_function_stub( func, n )
+                        self.printFunction(fake_func, fake_func.name)
 
 
-                       self.printFunction(func, func.name)
-                       if func.glx_sop and func.glx_vendorpriv:
-                               self.printFunction(func, func.glx_vendorpriv_names[0])
+            self.printFunction(func, func.name)
+            if func.glx_sop and func.glx_vendorpriv:
+                self.printFunction(func, func.glx_vendorpriv_names[0])
 
-               return
+        self.printGetProcAddress(api)
+        return
 
+    def printGetProcAddress(self, api):
+        procs = {}
+        for func in api.functionIterateGlx():
+            for n in func.entry_points:
+                if func.has_different_protocol(n):
+                    procs[n] = func.static_glx_name(n)
+
+        print("""
+#ifdef GLX_INDIRECT_RENDERING
+
+static const struct proc_pair
+{
+   const char *name;
+   _glapi_proc proc;
+} proc_pairs[%d] = {""" % len(procs))
+        names = sorted(procs.keys())
+        for i in range(len(names)):
+            comma = ',' if i < len(names) - 1 else ''
+            print('   { "%s", (_glapi_proc) gl%s }%s' % (names[i], procs[names[i]], comma))
+        print("""};
+
+static int
+__indirect_get_proc_compare(const void *key, const void *memb)
+{
+   const struct proc_pair *pair = (const struct proc_pair *) memb;
+   return strcmp((const char *) key, pair->name);
+}
 
-       def printFunction(self, func, name):
-               footer = '}\n'
-               if func.glx_rop == ~0:
-                       print 'static %s' % (func.return_type)
-                       print '%s( unsigned opcode, unsigned dim, %s )' % (func.name, func.get_parameter_string())
-                       print '{'
-               else:
-                       if func.has_different_protocol(name):
-                               if func.return_type == "void":
-                                       ret_string = ''
-                               else:
-                                       ret_string = "return "
+_glapi_proc
+__indirect_get_proc_address(const char *name)
+{
+   const struct proc_pair *pair;
+   
+   /* skip "gl" */
+   name += 2;
 
-                               func_name = func.static_glx_name(name)
-                               print '#define %s %d' % (func.opcode_vendor_name(name), func.glx_vendorpriv)
-                               print '%s gl%s(%s)' % (func.return_type, func_name, func.get_parameter_string())
-                               print '{'
-                               print '    struct glx_context * const gc = __glXGetCurrentContext();'
-                               print ''
-                               print '#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)'
-                               print '    if (gc->isDirect) {'
-                               print '    %sCALL_%s(GET_DISPATCH(), (%s));' % (ret_string, func.name, func.get_called_parameter_string())
-                               print '    } else'
-                               print '#endif'
-                               print '    {'
+   pair = (const struct proc_pair *) bsearch((const void *) name,
+      (const void *) proc_pairs, ARRAY_SIZE(proc_pairs), sizeof(proc_pairs[0]),
+      __indirect_get_proc_compare);
 
-                               footer = '}\n}\n'
-                       else:
-                               print '#define %s %d' % (func.opcode_name(), func.opcode_value())
+   return (pair) ? pair->proc : NULL;
+}
 
-                               print '%s __indirect_gl%s(%s)' % (func.return_type, name, func.get_parameter_string())
-                               print '{'
+#endif /* GLX_INDIRECT_RENDERING */
+""")
+        return
 
 
-               if func.glx_rop != 0 or func.vectorequiv != None:
-                       if len(func.images):
-                               self.printPixelFunction(func)
-                       else:
-                               self.printRenderFunction(func)
-               elif func.glx_sop != 0 or func.glx_vendorpriv != 0:
-                       self.printSingleFunction(func, name)
-                       pass
-               else:
-                       print "/* Missing GLX protocol for %s. */" % (name)
+    def printFunction(self, func, name):
+        footer = '}\n'
+        if func.glx_rop == ~0:
+            print('static %s' % (func.return_type))
+            print('%s( unsigned opcode, unsigned dim, %s )' % (func.name, func.get_parameter_string()))
+            print('{')
+        else:
+            if func.has_different_protocol(name):
+                if func.return_type == "void":
+                    ret_string = ''
+                else:
+                    ret_string = "return "
+
+                func_name = func.static_glx_name(name)
+                print('#define %s %d' % (func.opcode_vendor_name(name), func.glx_vendorpriv))
+                print('%s gl%s(%s)' % (func.return_type, func_name, func.get_parameter_string()))
+                print('{')
+                print('    struct glx_context * const gc = __glXGetCurrentContext();')
+                print('')
+                print('#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)')
+                print('    if (gc->isDirect) {')
+                print('        const _glapi_proc *const disp_table = (_glapi_proc *)GET_DISPATCH();')
+                print('        PFNGL%sPROC p =' % (name.upper()))
+                print('            (PFNGL%sPROC) disp_table[%d];' % (name.upper(), func.offset))
+                print('    %sp(%s);' % (ret_string, func.get_called_parameter_string()))
+                print('    } else')
+                print('#endif')
+                print('    {')
+
+                footer = '}\n}\n'
+            else:
+                print('#define %s %d' % (func.opcode_name(), func.opcode_value()))
+
+                print('%s __indirect_gl%s(%s)' % (func.return_type, name, func.get_parameter_string()))
+                print('{')
+
+
+        if func.glx_rop != 0 or func.vectorequiv != None:
+            if len(func.images):
+                self.printPixelFunction(func)
+            else:
+                self.printRenderFunction(func)
+        elif func.glx_sop != 0 or func.glx_vendorpriv != 0:
+            self.printSingleFunction(func, name)
+            pass
+        else:
+            print("/* Missing GLX protocol for %s. */" % (name))
 
-               print footer
-               return
+        print(footer)
+        return
 
 
-       def print_generic_function(self, n):
-               size = (n + 3) & ~3
-               print """static FASTCALL NOINLINE void
+    def print_generic_function(self, n):
+        size = (n + 3) & ~3
+        print("""static FASTCALL NOINLINE void
 generic_%u_byte( GLint rop, const void * ptr )
 {
     struct glx_context * const gc = __glXGetCurrentContext();
@@ -416,459 +489,485 @@ generic_%u_byte( GLint rop, const void * ptr )
     gc->pc += cmdlen;
     if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }
 }
-""" % (n, size + 4, size)
-               return
-
-
-       def common_emit_one_arg(self, p, pc, adjust, extra_offset):
-               if p.is_array():
-                       src_ptr = p.name
-               else:
-                       src_ptr = "&" + p.name
-
-               if p.is_padding:
-                       print '(void) memset((void *)(%s + %u), 0, %s);' \
-                           % (pc, p.offset + adjust, p.size_string() )
-               elif not extra_offset:
-                       print '(void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
-                           % (pc, p.offset + adjust, src_ptr, p.size_string() )
-               else:
-                       print '(void) memcpy((void *)(%s + %u + %s), (void *)(%s), %s);' \
-                           % (pc, p.offset + adjust, extra_offset, src_ptr, p.size_string() )
-
-       def common_emit_args(self, f, pc, adjust, skip_vla):
-               extra_offset = None
-
-               for p in f.parameterIterateGlxSend( not skip_vla ):
-                       if p.name != f.img_reset:
-                               self.common_emit_one_arg(p, pc, adjust, extra_offset)
-                               
-                               if p.is_variable_length():
-                                       temp = p.size_string()
-                                       if extra_offset:
-                                               extra_offset += " + %s" % (temp)
-                                       else:
-                                               extra_offset = temp
-
-               return
-
-
-       def pixel_emit_args(self, f, pc, large):
-               """Emit the arguments for a pixel function.  This differs from
-               common_emit_args in that pixel functions may require padding
-               be inserted (i.e., for the missing width field for
-               TexImage1D), and they may also require a 'NULL image' flag
-               be inserted before the image data."""
-
-               if large:
-                       adjust = 8
-               else:
-                       adjust = 4
-
-               for param in f.parameterIterateGlxSend():
-                       if not param.is_image():
-                               self.common_emit_one_arg(param, pc, adjust, None)
-
-                               if f.pad_after(param):
-                                       print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc, (param.offset + param.size()) + adjust)
-
-                       else:
-                               [dim, width, height, depth, extent] = param.get_dimensions()
-                               if f.glx_rop == ~0:
-                                       dim_str = "dim"
-                               else:
-                                       dim_str = str(dim)
-
-                               if param.is_padding:
-                                       print '(void) memset((void *)(%s + %u), 0, %s);' \
-                                       % (pc, (param.offset - 4) + adjust, param.size_string() )
-
-                               if param.img_null_flag:
-                                       if large:
-                                               print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc, (param.offset - 4) + adjust)
-                                       else:
-                                               print '(void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (pc, (param.offset - 4) + adjust, param.name)
-
-
-                               pixHeaderPtr = "%s + %u" % (pc, adjust)
-                               pcPtr = "%s + %u" % (pc, param.offset + adjust)
-
-                               if not large:
-                                       if param.img_send_null:
-                                               condition = '(compsize > 0) && (%s != NULL)' % (param.name)
-                                       else:
-                                               condition = 'compsize > 0'
-
-                                       print 'if (%s) {' % (condition)
-                                       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)
-                                       print '} else {'
-                                       print '    (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (pixHeaderPtr, dim, dim)
-                                       print '}'
-                               else:
-                                       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)
-
-               return
-
-
-       def large_emit_begin(self, f, op_name = None):
-               if not op_name:
-                       op_name = f.opcode_real_name()
-
-               print 'const GLint op = %s;' % (op_name)
-               print 'const GLuint cmdlenLarge = cmdlen + 4;'
-               print 'GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);'
-               print '(void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);'
-               print '(void) memcpy((void *)(pc + 4), (void *)(&op), 4);'
-               return
-
-
-       def common_func_print_just_start(self, f, name):
-               print '    struct glx_context * const gc = __glXGetCurrentContext();'
-
-               # The only reason that single and vendor private commands need
-               # a variable called 'dpy' is becuase they use the SyncHandle
-               # macro.  For whatever brain-dead reason, that macro is hard-
-               # coded to use a variable called 'dpy' instead of taking a
-               # parameter.
-
-               # FIXME Simplify the logic related to skip_condition and
-               # FIXME condition_list in this function.  Basically, remove
-               # FIXME skip_condition, and just append the "dpy != NULL" type
-               # FIXME condition to condition_list from the start.  The only
-               # FIXME reason it's done in this confusing way now is to
-               # FIXME minimize the diffs in the generated code.
-
-               if not f.glx_rop:
-                       for p in f.parameterIterateOutputs():
-                               if p.is_image() and (p.img_format != "GL_COLOR_INDEX" or p.img_type != "GL_BITMAP"):
-                                       print '    const __GLXattribute * const state = gc->client_state_private;'
-                                       break
-
-                       print '    Display * const dpy = gc->currentDpy;'
-                       skip_condition = "dpy != NULL"
-               elif f.can_be_large:
-                       skip_condition = "gc->currentDpy != NULL"
-               else:
-                       skip_condition = None
-
-
-               if f.return_type != 'void':
-                       print '    %s retval = (%s) 0;' % (f.return_type, f.return_type)
-
-
-               if name != None and name not in f.glx_vendorpriv_names:
-                       print '#ifndef USE_XCB'
-               self.emit_packet_size_calculation(f, 0)
-               if name != None and name not in f.glx_vendorpriv_names:
-                       print '#endif'
-
-               condition_list = []
-               for p in f.parameterIterateCounters():
-                       condition_list.append( "%s >= 0" % (p.name) )
-                       # 'counter' parameters cannot be negative
-                       print "    if (%s < 0) {" % p.name
-                       print "        __glXSetError(gc, GL_INVALID_VALUE);"
-                       if f.return_type != 'void':
-                               print "        return 0;"
-                       else:
-                               print "        return;"
-                       print "    }"
-
-               if skip_condition:
-                       condition_list.append( skip_condition )
-
-               if len( condition_list ) > 0:
-                       if len( condition_list ) > 1:
-                               skip_condition = "(%s)" % (string.join( condition_list, ") && (" ))
-                       else:
-                               skip_condition = "%s" % (condition_list.pop(0))
-
-                       print '    if (__builtin_expect(%s, 1)) {' % (skip_condition)
-                       return 1
-               else:
-                       return 0
-
-
-       def printSingleFunction(self, f, name):
-               self.common_func_print_just_start(f, name)
-
-               if self.debug:
-                       print '        printf( "Enter %%s...\\n", "gl%s" );' % (f.name)
-
-               if name not in f.glx_vendorpriv_names:
-
-                       # XCB specific:
-                       print '#ifdef USE_XCB'
-                       if self.debug:
-                               print '        printf("\\tUsing XCB.\\n");'
-                       print '        xcb_connection_t *c = XGetXCBConnection(dpy);'
-                       print '        (void) __glXFlushRenderBuffer(gc, gc->pc);'
-                       xcb_name = 'xcb_glx%s' % convertStringForXCB(name)
-
-                       iparams=[]
-                       extra_iparams = []
-                       output = None
-                       for p in f.parameterIterator():
-                               if p.is_output:
-                                       output = p
-
-                                       if p.is_image():
-                                               if p.img_format != "GL_COLOR_INDEX" or p.img_type != "GL_BITMAP":
-                                                       extra_iparams.append("state->storePack.swapEndian")
-                                               else:
-                                                       extra_iparams.append("0")
-                                       
-                                               # Hardcode this in.  lsb_first param (apparently always GL_FALSE)
-                                               # also present in GetPolygonStipple, but taken care of above.
-                                               if xcb_name == "xcb_glx_read_pixels": 
-                                                       extra_iparams.append("0")
-                               else:
-                                       iparams.append(p.name)
-
-
-                       xcb_request = '%s(%s)' % (xcb_name, ", ".join(["c", "gc->currentContextTag"] + iparams + extra_iparams))
-
-                       if f.needs_reply():
-                               print '        %s_reply_t *reply = %s_reply(c, %s, NULL);' % (xcb_name, xcb_name, xcb_request)
-                               if output and f.reply_always_array:
-                                       print '        (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output.name, xcb_name, xcb_name, output.get_base_type_string())
-
-                               elif output and not f.reply_always_array:
-                                       if not output.is_image():
-                                               print '        if (%s_data_length(reply) == 0)' % (xcb_name)
-                                               print '            (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output.name)
-                                               print '        else'
-                                       print '        (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output.name, xcb_name, xcb_name, output.get_base_type_string())
-
-
-                               if f.return_type != 'void':
-                                       print '        retval = reply->ret_val;'
-                               print '        free(reply);'
-                       else:
-                               print '        ' + xcb_request + ';'
-                       print '#else'
-                       # End of XCB specific.
-
-
-               if f.parameters != []:
-                       pc_decl = "GLubyte const * pc ="
-               else:
-                       pc_decl = "(void)"
-
-               if name in f.glx_vendorpriv_names:
-                       print '        %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl, f.opcode_real_name(), f.opcode_vendor_name(name))
-               else:
-                       print '        %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl, f.opcode_name())
-
-               self.common_emit_args(f, "pc", 0, 0)
-
-               images = f.get_images()
-
-               for img in images:
-                       if img.is_output:
-                               o = f.command_fixed_length() - 4
-                               print '        *(int32_t *)(pc + %u) = 0;' % (o)
-                               if img.img_format != "GL_COLOR_INDEX" or img.img_type != "GL_BITMAP":
-                                       print '        * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o)
-               
-                               if f.img_reset:
-                                       print '        * (int8_t *)(pc + %u) = %s;' % (o + 1, f.img_reset)
+""" % (n, size + 4, size))
+        return
 
 
-               return_name = ''
-               if f.needs_reply():
-                       if f.return_type != 'void':
-                               return_name = " retval"
-                               return_str = " retval = (%s)" % (f.return_type)
-                       else:
-                               return_str = " (void)"
-
-                       got_reply = 0
+    def common_emit_one_arg(self, p, pc, adjust, extra_offset):
+        if p.is_array():
+            src_ptr = p.name
+        else:
+            src_ptr = "&" + p.name
+
+        if p.is_padding:
+            print('(void) memset((void *)(%s + %u), 0, %s);' \
+                % (pc, p.offset + adjust, p.size_string() ))
+        elif not extra_offset:
+            print('(void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
+                % (pc, p.offset + adjust, src_ptr, p.size_string() ))
+        else:
+            print('(void) memcpy((void *)(%s + %u + %s), (void *)(%s), %s);' \
+                % (pc, p.offset + adjust, extra_offset, src_ptr, p.size_string() ))
+
+    def common_emit_args(self, f, pc, adjust, skip_vla):
+        extra_offset = None
 
-                       for p in f.parameterIterateOutputs():
-                               if p.is_image():
-                                       [dim, w, h, d, junk] = p.get_dimensions()
-                                       if f.dimensions_in_reply:
-                                               print "        __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim, p.img_format, p.img_type, p.name)
-                                       else:
-                                               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)
-
-                                       got_reply = 1
-                               else:
-                                       if f.reply_always_array:
-                                               aa = "GL_TRUE"
-                                       else:
-                                               aa = "GL_FALSE"
+        for p in f.parameterIterateGlxSend( not skip_vla ):
+            if p.name != f.img_reset:
+                self.common_emit_one_arg(p, pc, adjust, extra_offset)
 
-                                       # gl_parameter.size() returns the size
-                                       # of the entire data item.  If the
-                                       # item is a fixed-size array, this is
-                                       # the size of the whole array.  This
-                                       # is not what __glXReadReply wants. It
-                                       # wants the size of a single data
-                                       # element in the reply packet.
-                                       # Dividing by the array size (1 for
-                                       # non-arrays) gives us this.
+                if p.is_variable_length():
+                    temp = p.size_string()
+                    if extra_offset:
+                        extra_offset += " + %s" % (temp)
+                    else:
+                        extra_offset = temp
 
-                                       s = p.size() / p.get_element_count()
-                                       print "       %s __glXReadReply(dpy, %s, %s, %s);" % (return_str, s, p.name, aa)
-                                       got_reply = 1
+        return
 
 
-                       # If a reply wasn't read to fill an output parameter,
-                       # read a NULL reply to get the return value.
+    def pixel_emit_args(self, f, pc, large):
+        """Emit the arguments for a pixel function.  This differs from
+        common_emit_args in that pixel functions may require padding
+        be inserted (i.e., for the missing width field for
+        TexImage1D), and they may also require a 'NULL image' flag
+        be inserted before the image data."""
+
+        if large:
+            adjust = 8
+        else:
+            adjust = 4
+
+        for param in f.parameterIterateGlxSend():
+            if not param.is_image():
+                self.common_emit_one_arg(param, pc, adjust, None)
+
+                if f.pad_after(param):
+                    print('(void) memcpy((void *)(%s + %u), zero, 4);' % (pc, (param.offset + param.size()) + adjust))
+
+            else:
+                [dim, width, height, depth, extent] = param.get_dimensions()
+                if f.glx_rop == ~0:
+                    dim_str = "dim"
+                else:
+                    dim_str = str(dim)
+
+                if param.is_padding:
+                    print('(void) memset((void *)(%s + %u), 0, %s);' \
+                    % (pc, (param.offset - 4) + adjust, param.size_string() ))
+
+                if param.img_null_flag:
+                    if large:
+                        print('(void) memcpy((void *)(%s + %u), zero, 4);' % (pc, (param.offset - 4) + adjust))
+                    else:
+                        print('(void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (pc, (param.offset - 4) + adjust, param.name))
+
+
+                pixHeaderPtr = "%s + %u" % (pc, adjust)
+                pcPtr = "%s + %u" % (pc, param.offset + adjust)
+
+                if not large:
+                    if param.img_send_null:
+                        condition = '(compsize > 0) && (%s != NULL)' % (param.name)
+                    else:
+                        condition = 'compsize > 0'
+
+                    print('if (%s) {' % (condition))
+                    print('    __glFillImage(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))
+                    print('} else {')
+                    print('    (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (pixHeaderPtr, dim, dim))
+                    print('}')
+                else:
+                    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))
+
+        return
+
+
+    def large_emit_begin(self, f, op_name = None):
+        if not op_name:
+            op_name = f.opcode_real_name()
+
+        print('const GLint op = %s;' % (op_name))
+        print('const GLuint cmdlenLarge = cmdlen + 4;')
+        print('GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);')
+        print('(void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);')
+        print('(void) memcpy((void *)(pc + 4), (void *)(&op), 4);')
+        return
+
+
+    def common_func_print_just_start(self, f, name):
+        print('    struct glx_context * const gc = __glXGetCurrentContext();')
+
+        # The only reason that single and vendor private commands need
+        # a variable called 'dpy' is because they use the SyncHandle
+        # macro.  For whatever brain-dead reason, that macro is hard-
+        # coded to use a variable called 'dpy' instead of taking a
+        # parameter.
+
+        # FIXME Simplify the logic related to skip_condition and
+        # FIXME condition_list in this function.  Basically, remove
+        # FIXME skip_condition, and just append the "dpy != NULL" type
+        # FIXME condition to condition_list from the start.  The only
+        # FIXME reason it's done in this confusing way now is to
+        # FIXME minimize the diffs in the generated code.
+
+        if not f.glx_rop:
+            for p in f.parameterIterateOutputs():
+                if p.is_image() and (p.img_format != "GL_COLOR_INDEX" or p.img_type != "GL_BITMAP"):
+                    print('    const __GLXattribute * const state = gc->client_state_private;')
+                    break
+
+            print('    Display * const dpy = gc->currentDpy;')
+            skip_condition = "dpy != NULL"
+        elif f.can_be_large:
+            skip_condition = "gc->currentDpy != NULL"
+        else:
+            skip_condition = None
+
+
+        if f.return_type != 'void':
+            print('    %s retval = (%s) 0;' % (f.return_type, f.return_type))
+
+
+        if name != None and name not in f.glx_vendorpriv_names:
+            print('#ifndef USE_XCB')
+        self.emit_packet_size_calculation(f, 0)
+        if name != None and name not in f.glx_vendorpriv_names:
+            print('#endif')
+
+        if f.command_variable_length() != "":
+            print("    if (0%s < 0) {" % f.command_variable_length())
+            print("        __glXSetError(gc, GL_INVALID_VALUE);")
+            if f.return_type != 'void':
+                print("        return 0;")
+            else:
+                print("        return;")
+            print("    }")
+
+        condition_list = []
+        for p in f.parameterIterateCounters():
+            condition_list.append( "%s >= 0" % (p.name) )
+            # 'counter' parameters cannot be negative
+            print("    if (%s < 0) {" % p.name)
+            print("        __glXSetError(gc, GL_INVALID_VALUE);")
+            if f.return_type != 'void':
+                print("        return 0;")
+            else:
+                print("        return;")
+            print("    }")
+
+        if skip_condition:
+            condition_list.append( skip_condition )
+
+        if len( condition_list ) > 0:
+            if len( condition_list ) > 1:
+                skip_condition = "(%s)" % ") && (".join( condition_list )
+            else:
+                skip_condition = "%s" % (condition_list.pop(0))
+
+            print('    if (__builtin_expect(%s, 1)) {' % (skip_condition))
+            return 1
+        else:
+            return 0
+
+
+    def printSingleFunction(self, f, name):
+        self.common_func_print_just_start(f, name)
+
+        if self.debug:
+            print('        printf( "Enter %%s...\\n", "gl%s" );' % (f.name))
+
+        if name not in f.glx_vendorpriv_names:
+
+            # XCB specific:
+            print('#ifdef USE_XCB')
+            if self.debug:
+                print('        printf("\\tUsing XCB.\\n");')
+            print('        xcb_connection_t *c = XGetXCBConnection(dpy);')
+            print('        (void) __glXFlushRenderBuffer(gc, gc->pc);')
+            xcb_name = 'xcb_glx%s' % convertStringForXCB(name)
+
+            iparams=[]
+            extra_iparams = []
+            output = None
+            for p in f.parameterIterator():
+                if p.is_output:
+                    output = p
+
+                    if p.is_image():
+                        if p.img_format != "GL_COLOR_INDEX" or p.img_type != "GL_BITMAP":
+                            extra_iparams.append("state->storePack.swapEndian")
+                        else:
+                            extra_iparams.append("0")
+
+                        # Hardcode this in.  lsb_first param (apparently always GL_FALSE)
+                        # also present in GetPolygonStipple, but taken care of above.
+                        if xcb_name == "xcb_glx_read_pixels": 
+                            extra_iparams.append("0")
+                else:
+                    iparams.append(p.name)
+
+
+            xcb_request = '%s(%s)' % (xcb_name, ", ".join(["c", "gc->currentContextTag"] + iparams + extra_iparams))
+
+            if f.needs_reply():
+                print('        %s_reply_t *reply = %s_reply(c, %s, NULL);' % (xcb_name, xcb_name, xcb_request))
+                if output:
+                    if output.is_image():
+                        [dim, w, h, d, junk] = output.get_dimensions()
+                        if f.dimensions_in_reply:
+                            w = "reply->width"
+                            h = "reply->height"
+                            d = "reply->depth"
+                            if dim < 2:
+                                h = "1"
+                            else:
+                                print('        if (%s == 0) { %s = 1; }' % (h, h))
+                            if dim < 3:
+                                d = "1"
+                            else:
+                                print('        if (%s == 0) { %s = 1; }' % (d, d))
+
+                        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))
+                    else:
+                        if f.reply_always_array:
+                            print('        (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output.name, xcb_name, xcb_name, output.get_base_type_string()))
+                        else:
+                            print('        /* the XXX_data_length() xcb function name is misleading, it returns the number */')
+                            print('        /* of elements, not the length of the data part. A single element is embedded. */')
+                            print('        if (%s_data_length(reply) == 1)' % (xcb_name))
+                            print('            (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output.name))
+                            print('        else')
+                            print('            (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output.name, xcb_name, xcb_name, output.get_base_type_string()))
+
+                if f.return_type != 'void':
+                    print('        retval = reply->ret_val;')
+                print('        free(reply);')
+            else:
+                print('        ' + xcb_request + ';')
+            print('#else')
+            # End of XCB specific.
+
+
+        if f.parameters != []:
+            pc_decl = "GLubyte const * pc ="
+        else:
+            pc_decl = "(void)"
+
+        if name in f.glx_vendorpriv_names:
+            print('        %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl, f.opcode_real_name(), f.opcode_vendor_name(name)))
+        else:
+            print('        %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl, f.opcode_name()))
 
-                       if not got_reply:
-                               print "       %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str)
+        self.common_emit_args(f, "pc", 0, 0)
 
+        images = f.get_images()
 
-               elif self.debug:
-                       # Only emit the extra glFinish call for functions
-                       # that don't already require a reply from the server.
-                       print '        __indirect_glFinish();'
+        for img in images:
+            if img.is_output:
+                o = f.command_fixed_length() - 4
+                print('        *(int32_t *)(pc + %u) = 0;' % (o))
+                if img.img_format != "GL_COLOR_INDEX" or img.img_type != "GL_BITMAP":
+                    print('        * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o))
 
-               if self.debug:
-                       print '        printf( "Exit %%s.\\n", "gl%s" );' % (name)
+                if f.img_reset:
+                    print('        * (int8_t *)(pc + %u) = %s;' % (o + 1, f.img_reset))
 
 
-               print '        UnlockDisplay(dpy); SyncHandle();'
+        return_name = ''
+        if f.needs_reply():
+            if f.return_type != 'void':
+                return_name = " retval"
+                return_str = " retval = (%s)" % (f.return_type)
+            else:
+                return_str = " (void)"
 
-               if name not in f.glx_vendorpriv_names:
-                       print '#endif /* USE_XCB */'
+            got_reply = 0
 
-               print '    }'
-               print '    return%s;' % (return_name)
-               return
+            for p in f.parameterIterateOutputs():
+                if p.is_image():
+                    [dim, w, h, d, junk] = p.get_dimensions()
+                    if f.dimensions_in_reply:
+                        print("        __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim, p.img_format, p.img_type, p.name))
+                    else:
+                        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))
 
+                    got_reply = 1
+                else:
+                    if f.reply_always_array:
+                        aa = "GL_TRUE"
+                    else:
+                        aa = "GL_FALSE"
 
-       def printPixelFunction(self, f):
-               if self.pixel_stubs.has_key( f.name ):
-                       # Normally gl_function::get_parameter_string could be
-                       # used.  However, this call needs to have the missing
-                       # dimensions (e.g., a fake height value for
-                       # glTexImage1D) added in.
+                    # gl_parameter.size() returns the size
+                    # of the entire data item.  If the
+                    # item is a fixed-size array, this is
+                    # the size of the whole array.  This
+                    # is not what __glXReadReply wants. It
+                    # wants the size of a single data
+                    # element in the reply packet.
+                    # Dividing by the array size (1 for
+                    # non-arrays) gives us this.
 
-                       p_string = ""
-                       for param in f.parameterIterateGlxSend():
-                               if param.is_padding:
-                                       continue
+                    s = p.size() // p.get_element_count()
+                    print("       %s __glXReadReply(dpy, %s, %s, %s);" % (return_str, s, p.name, aa))
+                    got_reply = 1
 
-                               p_string += ", " + param.name
 
-                               if param.is_image():
-                                       [dim, junk, junk, junk, junk] = param.get_dimensions()
+            # If a reply wasn't read to fill an output parameter,
+            # read a NULL reply to get the return value.
 
-                               if f.pad_after(param):
-                                       p_string += ", 1"
+            if not got_reply:
+                print("       %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str))
 
-                       print '    %s(%s, %u%s );' % (self.pixel_stubs[f.name] , f.opcode_name(), dim, p_string)
-                       return
 
+        elif self.debug:
+            # Only emit the extra glFinish call for functions
+            # that don't already require a reply from the server.
+            print('        __indirect_glFinish();')
 
-               if self.common_func_print_just_start(f, None):
-                       trailer = "    }"
-               else:
-                       trailer = None
+        if self.debug:
+            print('        printf( "Exit %%s.\\n", "gl%s" );' % (name))
 
 
-               if f.can_be_large:
-                       print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
-                       print '    if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
-                       print '        (void) __glXFlushRenderBuffer(gc, gc->pc);'
-                       print '    }'
+        print('        UnlockDisplay(dpy); SyncHandle();')
 
-               if f.glx_rop == ~0:
-                       opcode = "opcode"
-               else:
-                       opcode = f.opcode_real_name()
+        if name not in f.glx_vendorpriv_names:
+            print('#endif /* USE_XCB */')
 
-               print 'emit_header(gc->pc, %s, cmdlen);' % (opcode)
+        print('    }')
+        print('    return%s;' % (return_name))
+        return
 
-               self.pixel_emit_args( f, "gc->pc", 0 )
-               print 'gc->pc += cmdlen;'
-               print 'if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
 
-               if f.can_be_large:
-                       print '}'
-                       print 'else {'
+    def printPixelFunction(self, f):
+        if f.name in self.pixel_stubs:
+            # Normally gl_function::get_parameter_string could be
+            # used.  However, this call needs to have the missing
+            # dimensions (e.g., a fake height value for
+            # glTexImage1D) added in.
 
-                       self.large_emit_begin(f, opcode)
-                       self.pixel_emit_args(f, "pc", 1)
+            p_string = ""
+            for param in f.parameterIterateGlxSend():
+                if param.is_padding:
+                    continue
 
-                       print '}'
+                p_string += ", " + param.name
 
-               if trailer: print trailer
-               return
+                if param.is_image():
+                    [dim, junk, junk, junk, junk] = param.get_dimensions()
 
+                if f.pad_after(param):
+                    p_string += ", 1"
 
-       def printRenderFunction(self, f):
-               # There is a class of GL functions that take a single pointer
-               # as a parameter.  This pointer points to a fixed-size chunk
-               # of data, and the protocol for this functions is very
-               # regular.  Since they are so regular and there are so many
-               # of them, special case them with generic functions.  On
-               # x86, this saves about 26KB in the libGL.so binary.
+            print('    %s(%s, %u%s );' % (self.pixel_stubs[f.name] , f.opcode_name(), dim, p_string))
+            return
 
-               if f.variable_length_parameter() == None and len(f.parameters) == 1:
-                       p = f.parameters[0]
-                       if p.is_pointer():
-                               cmdlen = f.command_fixed_length()
-                               if cmdlen in self.generic_sizes:
-                                       print '    generic_%u_byte( %s, %s );' % (cmdlen, f.opcode_real_name(), p.name)
-                                       return
 
-               if self.common_func_print_just_start(f, None):
-                       trailer = "    }"
-               else:
-                       trailer = None
+        if self.common_func_print_just_start(f, None):
+            trailer = "    }"
+        else:
+            trailer = None
 
-               if self.debug:
-                       print 'printf( "Enter %%s...\\n", "gl%s" );' % (f.name)
 
-               if f.can_be_large:
-                       print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
-                       print '    if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
-                       print '        (void) __glXFlushRenderBuffer(gc, gc->pc);'
-                       print '    }'
+        if f.can_be_large:
+            print('if (cmdlen <= gc->maxSmallRenderCommandSize) {')
+            print('    if ( (gc->pc + cmdlen) > gc->bufEnd ) {')
+            print('        (void) __glXFlushRenderBuffer(gc, gc->pc);')
+            print('    }')
 
-               print 'emit_header(gc->pc, %s, cmdlen);' % (f.opcode_real_name())
+        if f.glx_rop == ~0:
+            opcode = "opcode"
+        else:
+            opcode = f.opcode_real_name()
 
-               self.common_emit_args(f, "gc->pc", 4, 0)
-               print 'gc->pc += cmdlen;'
-               print 'if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
+        print('emit_header(gc->pc, %s, cmdlen);' % (opcode))
 
-               if f.can_be_large:
-                       print '}'
-                       print 'else {'
+        self.pixel_emit_args( f, "gc->pc", 0 )
+        print('gc->pc += cmdlen;')
+        print('if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }')
 
-                       self.large_emit_begin(f)
-                       self.common_emit_args(f, "pc", 8, 1)
+        if f.can_be_large:
+            print('}')
+            print('else {')
 
-                       p = f.variable_length_parameter()
-                       print '    __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (p.offset + 8, p.name, p.size_string())
-                       print '}'
+            self.large_emit_begin(f, opcode)
+            self.pixel_emit_args(f, "pc", 1)
 
-               if self.debug:
-                       print '__indirect_glFinish();'
-                       print 'printf( "Exit %%s.\\n", "gl%s" );' % (f.name)
+            print('}')
 
-               if trailer: print trailer
-               return
+        if trailer: print(trailer)
+        return
+
+
+    def printRenderFunction(self, f):
+        # There is a class of GL functions that take a single pointer
+        # as a parameter.  This pointer points to a fixed-size chunk
+        # of data, and the protocol for this functions is very
+        # regular.  Since they are so regular and there are so many
+        # of them, special case them with generic functions.  On
+        # x86, this saves about 26KB in the libGL.so binary.
+
+        if f.variable_length_parameter() == None and len(f.parameters) == 1:
+            p = f.parameters[0]
+            if p.is_pointer():
+                cmdlen = f.command_fixed_length()
+                if cmdlen in self.generic_sizes:
+                    print('    generic_%u_byte( %s, %s );' % (cmdlen, f.opcode_real_name(), p.name))
+                    return
+
+        if self.common_func_print_just_start(f, None):
+            trailer = "    }"
+        else:
+            trailer = None
+
+        if self.debug:
+            print('printf( "Enter %%s...\\n", "gl%s" );' % (f.name))
+
+        if f.can_be_large:
+            print('if (cmdlen <= gc->maxSmallRenderCommandSize) {')
+            print('    if ( (gc->pc + cmdlen) > gc->bufEnd ) {')
+            print('        (void) __glXFlushRenderBuffer(gc, gc->pc);')
+            print('    }')
+
+        print('emit_header(gc->pc, %s, cmdlen);' % (f.opcode_real_name()))
+
+        self.common_emit_args(f, "gc->pc", 4, 0)
+        print('gc->pc += cmdlen;')
+        print('if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }')
+
+        if f.can_be_large:
+            print('}')
+            print('else {')
+
+            self.large_emit_begin(f)
+            self.common_emit_args(f, "pc", 8, 1)
+
+            p = f.variable_length_parameter()
+            print('    __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (p.offset + 8, p.name, p.size_string()))
+            print('}')
+
+        if self.debug:
+            print('__indirect_glFinish();')
+            print('printf( "Exit %%s.\\n", "gl%s" );' % (f.name))
+
+        if trailer: print(trailer)
+        return
 
 
 class PrintGlxProtoInit_c(gl_XML.gl_print_base):
-       def __init__(self):
-               gl_XML.gl_print_base.__init__(self)
+    def __init__(self):
+        gl_XML.gl_print_base.__init__(self)
 
-               self.name = "glX_proto_send.py (from Mesa)"
-               self.license = license.bsd_license_template % ( \
+        self.name = "glX_proto_send.py (from Mesa)"
+        self.license = license.bsd_license_template % ( \
 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
-               return
+        return
 
 
-       def printRealHeader(self):
-               print """/**
+    def printRealHeader(self):
+        print("""/**
  * \\file indirect_init.c
  * Initialize indirect rendering dispatch table.
  *
@@ -880,7 +979,9 @@ class PrintGlxProtoInit_c(gl_XML.gl_print_base):
 #include "indirect_init.h"
 #include "indirect.h"
 #include "glapi.h"
+#include <assert.h>
 
+#ifndef GLX_USE_APPLEGL
 
 /**
  * No-op function used to initialize functions that have no GLX protocol
@@ -897,146 +998,162 @@ static int NoOp(void)
  */
 struct _glapi_table * __glXNewIndirectAPI( void )
 {
-    struct _glapi_table *glAPI;
-    GLuint entries;
+    _glapi_proc *table;
+    unsigned entries;
+    unsigned i;
+    int o;
 
     entries = _glapi_get_dispatch_table_size();
-    glAPI = (struct _glapi_table *) Xmalloc(entries * sizeof(void *));
+    table = malloc(entries * sizeof(_glapi_proc));
+    if (table == NULL)
+        return NULL;
 
     /* 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;
-       }
+    for (i = 0; i < entries; i++) {
+       table[i] = (_glapi_proc) NoOp;
     }
 
-    /* now, initialize the entries we understand */"""
+    /* now, initialize the entries we understand */""")
 
-       def printRealFooter(self):
-               print """
-    return glAPI;
+    def printRealFooter(self):
+        print("""
+    return (struct _glapi_table *) table;
 }
-"""
-               return
+
+#endif
+""")
+        return
 
 
-       def printBody(self, api):
-               for [name, number] in api.categoryIterate():
-                       if number != None:
-                               preamble = '\n    /* %3u. %s */\n\n' % (int(number), name)
-                       else:
-                               preamble = '\n    /* %s */\n\n' % (name)
+    def printBody(self, api):
+        for [name, number] in api.categoryIterate():
+            if number != None:
+                preamble = '\n    /* %3u. %s */\n' % (int(number), name)
+            else:
+                preamble = '\n    /* %s */\n' % (name)
 
-                       for func in api.functionIterateByCategory(name):
-                               if func.client_supported_for_indirect():
-                                       print '%s    glAPI->%s = __indirect_gl%s;' % (preamble, func.name, func.name)
-                                       preamble = ''
+            for func in api.functionIterateByCategory(name):
+                if func.client_supported_for_indirect():
+                    if preamble:
+                        print(preamble)
+                        preamble = None
 
-               return
+                    if func.is_abi():
+                        print('    table[{offset}] = (_glapi_proc) __indirect_gl{name};'.format(name = func.name, offset = func.offset))
+                    else:
+                        print('    o = _glapi_get_proc_offset("gl{0}");'.format(func.name))
+                        print('    assert(o > 0);')
+                        print('    table[o] = (_glapi_proc) __indirect_gl{0};'.format(func.name))
+
+        return
 
 
 class PrintGlxProtoInit_h(gl_XML.gl_print_base):
-       def __init__(self):
-               gl_XML.gl_print_base.__init__(self)
+    def __init__(self):
+        gl_XML.gl_print_base.__init__(self)
 
-               self.name = "glX_proto_send.py (from Mesa)"
-               self.license = license.bsd_license_template % ( \
+        self.name = "glX_proto_send.py (from Mesa)"
+        self.license = license.bsd_license_template % ( \
 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
-               self.header_tag = "_INDIRECT_H_"
+        self.header_tag = "_INDIRECT_H_"
 
-               self.last_category = ""
-               return
+        self.last_category = ""
+        return
 
 
-       def printRealHeader(self):
-               print """/**
+    def printRealHeader(self):
+        print("""/**
  * \\file
  * Prototypes for indirect rendering functions.
  *
  * \\author Kevin E. Martin <kevin@precisioninsight.com>
  * \\author Ian Romanick <idr@us.ibm.com>
  */
-"""
-               self.printVisibility( "HIDDEN", "hidden" )
-               self.printFastcall()
-               self.printNoinline()
+""")
+        self.printFastcall()
+        self.printNoinline()
 
-               print """
+        print("""
+#include <X11/Xfuncproto.h>
 #include "glxclient.h"
 
-extern HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
+extern _X_HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
     void * dest, GLboolean reply_is_always_array );
 
-extern HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
+extern _X_HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
     struct glx_context * gc, unsigned max_dim, GLint width, GLint height,
     GLint depth, GLenum format, GLenum type, void * dest,
     GLboolean dimensions_in_reply );
 
-extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
+extern _X_HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
     struct glx_context * gc, GLint sop, GLint cmdlen );
 
-extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
+extern _X_HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
     struct glx_context * gc, GLint code, GLint vop, GLint cmdlen );
-"""
-
-
-       def printBody(self, api):
-               for func in api.functionIterateGlx():
-                       params = func.get_parameter_string()
-
-                       print 'extern HIDDEN %s __indirect_gl%s(%s);' % (func.return_type, func.name, params)
-
-                       for n in func.entry_points:
-                               if func.has_different_protocol(n):
-                                       asdf = func.static_glx_name(n)
-                                       if asdf not in func.static_entry_points:
-                                               print 'extern HIDDEN %s gl%s(%s);' % (func.return_type, asdf, params)
-                                       else:
-                                               print 'GLAPI %s GLAPIENTRY gl%s(%s);' % (func.return_type, asdf, params)
-                                               
-                                       break
-
-
-
-def show_usage():
-       print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys.argv[0]
-       print "    -m output_mode   Output mode can be one of 'proto', 'init_c' or 'init_h'."
-       print "    -d               Enable extra debug information in the generated code."
-       sys.exit(1)
+""")
+
+
+    def printBody(self, api):
+        for func in api.functionIterateGlx():
+            params = func.get_parameter_string()
+
+            print('extern _X_HIDDEN %s __indirect_gl%s(%s);' % (func.return_type, func.name, params))
+
+            for n in func.entry_points:
+                if func.has_different_protocol(n):
+                    asdf = func.static_glx_name(n)
+                    if asdf not in func.static_entry_points:
+                        print('extern _X_HIDDEN %s gl%s(%s);' % (func.return_type, asdf, params))
+                        # give it a easy-to-remember name
+                        if func.client_handcode:
+                            print('#define gl_dispatch_stub_%s gl%s' % (n, asdf))
+                    else:
+                        print('GLAPI %s GLAPIENTRY gl%s(%s);' % (func.return_type, asdf, params))
+
+                    break
+
+        print('')
+        print('#ifdef GLX_INDIRECT_RENDERING')
+        print('extern _X_HIDDEN void (*__indirect_get_proc_address(const char *name))(void);')
+        print('#endif')
+
+
+def _parser():
+    """Parse input and returned a parsed namespace."""
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-f',
+                        default='gl_API.xml',
+                        dest='filename',
+                        help='An XML file describing an API')
+    parser.add_argument('-m',
+                        required=True,
+                        dest='mode',
+                        choices=frozenset(['proto', 'init_c', 'init_h']),
+                        help='which file to generate')
+    parser.add_argument('-d',
+                        action='store_true',
+                        dest='debug',
+                        help='turn debug mode on.')
+    return parser.parse_args()
+
+
+def main():
+    """Main function."""
+    args = _parser()
+
+    if args.mode == "proto":
+        printer = PrintGlxProtoStubs()
+    elif args.mode == "init_c":
+        printer = PrintGlxProtoInit_c()
+    elif args.mode == "init_h":
+        printer = PrintGlxProtoInit_h()
+
+    printer.debug = args.debug
+    api = gl_XML.parse_GL_API(args.filename, glX_XML.glx_item_factory())
+
+    printer.Print( api )
 
 
 if __name__ == '__main__':
-       file_name = "gl_API.xml"
-
-       try:
-               (args, trail) = getopt.getopt(sys.argv[1:], "f:m:d")
-       except Exception,e:
-               show_usage()
-
-       debug = 0
-       mode = "proto"
-       for (arg,val) in args:
-               if arg == "-f":
-                       file_name = val
-               elif arg == "-m":
-                       mode = val
-               elif arg == "-d":
-                       debug = 1
-
-       if mode == "proto":
-               printer = PrintGlxProtoStubs()
-       elif mode == "init_c":
-               printer = PrintGlxProtoInit_c()
-       elif mode == "init_h":
-               printer = PrintGlxProtoInit_h()
-       else:
-               show_usage()
-
-
-       printer.debug = debug
-       api = gl_XML.parse_GL_API( file_name, glX_XML.glx_item_factory() )
-
-       printer.Print( api )
+    main()