mesa: Custom thread marshalling for Flush.
[mesa.git] / src / mapi / glapi / gen / glX_server_table.py
index f3962f875b08a3bfb8c02af56212a5fdeb85968e..f2e664264750c647193cfff84de2dde3f39291b2 100644 (file)
@@ -1,4 +1,3 @@
-#!/bin/env python
 
 # (C) Copyright IBM Corporation 2005, 2006
 # All Rights Reserved.
 # Authors:
 #    Ian Romanick <idr@us.ibm.com>
 
+import argparse
+
 import gl_XML, glX_XML, glX_proto_common, license
-import sys, getopt
 
 
 def log2(value):
-       for i in range(0, 30):
-               p = 1 << i
-               if p >= value:
-                       return i
+    for i in range(0, 30):
+        p = 1 << i
+        if p >= value:
+            return i
 
-       return -1
+    return -1
 
 
 def round_down_to_power_of_two(n):
-       """Returns the nearest power-of-two less than or equal to n."""
+    """Returns the nearest power-of-two less than or equal to n."""
 
-       for i in range(30, 0, -1):
-               p = 1 << i
-               if p <= n:
-                       return p
+    for i in range(30, 0, -1):
+        p = 1 << i
+        if p <= n:
+            return p
 
-       return -1
+    return -1
 
 
 class function_table:
-       def __init__(self, name, do_size_check):
-               self.name_base = name
-               self.do_size_check = do_size_check
-
-
-               self.max_bits = 1
-               self.next_opcode_threshold = (1 << self.max_bits)
-               self.max_opcode = 0
-
-               self.functions = {}
-               self.lookup_table = []
-               
-               # Minimum number of opcodes in a leaf node.
-               self.min_op_bits = 3
-               self.min_op_count = (1 << self.min_op_bits)
-               return
+    def __init__(self, name, do_size_check):
+        self.name_base = name
+        self.do_size_check = do_size_check
 
 
-       def append(self, opcode, func):
-               self.functions[opcode] = func
+        self.max_bits = 1
+        self.next_opcode_threshold = (1 << self.max_bits)
+        self.max_opcode = 0
 
-               if opcode > self.max_opcode:
-                       self.max_opcode = opcode
+        self.functions = {}
+        self.lookup_table = []
 
-                       if opcode > self.next_opcode_threshold:
-                               bits = log2(opcode)
-                               if (1 << bits) <= opcode:
-                                       bits += 1
+        # Minimum number of opcodes in a leaf node.
+        self.min_op_bits = 3
+        self.min_op_count = (1 << self.min_op_bits)
+        return
 
-                               self.max_bits = bits
-                               self.next_opcode_threshold = 1 << bits
-               return
 
+    def append(self, opcode, func):
+        self.functions[opcode] = func
 
-       def divide_group(self, min_opcode, total):
-               """Divide the group starting min_opcode into subgroups.
-               Returns a tuple containing the number of bits consumed by
-               the node, the list of the children's tuple, and the number
-               of entries in the final array used by this node and its
-               children, and the depth of the subtree rooted at the node."""
-
-               remaining_bits = self.max_bits - total
-               next_opcode = min_opcode + (1 << remaining_bits)
-               empty_children = 0
-               
-               for M in range(0, remaining_bits):
-                       op_count = 1 << (remaining_bits - M);
-                       child_count = 1 << M;
-
-                       empty_children = 0
-                       full_children = 0
-                       for i in range(min_opcode, next_opcode, op_count):
-                               used = 0
-                               empty = 0
+        if opcode > self.max_opcode:
+            self.max_opcode = opcode
 
-                               for j in range(i, i + op_count):
-                                       if self.functions.has_key(j):
-                                               used += 1;
-                                       else:
-                                               empty += 1;
-                                               
+            if opcode > self.next_opcode_threshold:
+                bits = log2(opcode)
+                if (1 << bits) <= opcode:
+                    bits += 1
 
-                               if empty == op_count:
-                                       empty_children += 1
-
-                               if used == op_count:
-                                       full_children += 1
-
-                       if (empty_children > 0) or (full_children == child_count) or (op_count <= self.min_op_count):
-                               break
+                self.max_bits = bits
+                self.next_opcode_threshold = 1 << bits
+        return
 
 
-               # If all the remaining bits are used by this node, as is the
-               # case when M is 0 or remaining_bits, the node is a leaf.
-
-               if (M == 0) or (M == remaining_bits):
-                       return [remaining_bits, [], 0, 0]
-               else:
-                       children = []
-                       count = 1
-                       depth = 1
-                       all_children_are_nonempty_leaf_nodes = 1
-                       for i in range(min_opcode, next_opcode, op_count):
-                               n = self.divide_group(i, total + M)
+    def divide_group(self, min_opcode, total):
+        """Divide the group starting min_opcode into subgroups.
+        Returns a tuple containing the number of bits consumed by
+        the node, the list of the children's tuple, and the number
+        of entries in the final array used by this node and its
+        children, and the depth of the subtree rooted at the node."""
 
-                               if not (n[1] == [] and not self.is_empty_leaf(i, n[0])):
-                                       all_children_are_nonempty_leaf_nodes = 0
+        remaining_bits = self.max_bits - total
+        next_opcode = min_opcode + (1 << remaining_bits)
+        empty_children = 0
 
-                               children.append(n)
-                               count += n[2] + 1
-                               
-                               if n[3] >= depth:
-                                       depth = n[3] + 1
-
-                       # If all of the child nodes are non-empty leaf nodes, pull
-                       # them up and make this node a leaf.
-
-                       if all_children_are_nonempty_leaf_nodes:
-                               return [remaining_bits, [], 0, 0]
-                       else:
-                               return [M, children, count, depth]
-
-
-       def is_empty_leaf(self, base_opcode, M):
-               for op in range(base_opcode, base_opcode + (1 << M)):
-                       if self.functions.has_key(op):
-                               return 0
-                               break
-
-               return 1
-
-
-       def dump_tree(self, node, base_opcode, remaining_bits, base_entry, depth):
-               M = node[0]
-               children = node[1]
-               child_M = remaining_bits - M
-
-
-               # This actually an error condition.
-               if children == []:
-                       return
-
-               print '    /* [%u] -> opcode range [%u, %u], node depth %u */' % (base_entry, base_opcode, base_opcode + (1 << remaining_bits), depth)
-               print '    %u,' % (M)
-
-               base_entry += (1 << M) + 1
-
-               child_index = base_entry
-               child_base_opcode = base_opcode
-               for child in children:
-                       if child[1] == []:
-                               if self.is_empty_leaf(child_base_opcode, child_M):
-                                       print '    EMPTY_LEAF,'
-                               else:
-                                       # Emit the index of the next dispatch
-                                       # function.  Then add all the
-                                       # dispatch functions for this leaf
-                                       # node to the dispatch function
-                                       # lookup table.
-
-                                       print '    LEAF(%u),' % (len(self.lookup_table))
-
-                                       for op in range(child_base_opcode, child_base_opcode + (1 << child_M)):
-                                               if self.functions.has_key(op):
-                                                       func = self.functions[op]
-                                                       size = func.command_fixed_length()
-
-                                                       if func.glx_rop != 0:
-                                                               size += 4
-
-                                                       size = ((size + 3) & ~3)
-
-                                                       if func.has_variable_size_request():
-                                                               size_name = "__glX%sReqSize" % (func.name)
-                                                       else:
-                                                               size_name = ""
-
-                                                       if func.glx_vendorpriv == op:
-                                                               func_name = func.glx_vendorpriv_names[0]
-                                                       else:
-                                                               func_name = func.name
-
-                                                       temp = [op, "__glXDisp_%s" % (func_name), "__glXDispSwap_%s" % (func_name), size, size_name]
-                                               else:
-                                                       temp = [op, "NULL", "NULL", 0, ""]
-
-                                               self.lookup_table.append(temp)
-                       else:
-                               print '    %u,' % (child_index)
-                               child_index += child[2]
-
-                       child_base_opcode += 1 << child_M
-
-               print ''
-
-               child_index = base_entry
-               for child in children:
-                       if child[1] != []:
-                               self.dump_tree(child, base_opcode, remaining_bits - M, child_index, depth + 1)
-                               child_index += child[2]
-
-                       base_opcode += 1 << (remaining_bits - M)
-
-
-       def Print(self):
-               # Each dispatch table consists of two data structures.
-               #
-               # The first structure is an N-way tree where the opcode for
-               # the function is the key.  Each node switches on a range of
-               # bits from the opcode.  M bits are extracted from the opcde
-               # and are used as an index to select one of the N, where
-               # N = 2^M, children.
-               #
-               # The tree is stored as a flat array.  The first value is the
-               # number of bits, M, used by the node.  For inner nodes, the
-               # following 2^M values are indexes into the array for the
-               # child nodes.  For leaf nodes, the followign 2^M values are
-               # indexes into the second data structure.
-               #
-               # If an inner node's child index is 0, the child is an empty
-               # leaf node.  That is, none of the opcodes selectable from
-               # that child exist.  Since most of the possible opcode space
-               # is unused, this allows compact data storage.
-               #
-               # The second data structure is an array of pairs of function
-               # pointers.  Each function contains a pointer to a protocol
-               # decode function and a pointer to a byte-swapped protocol
-               # decode function.  Elements in this array are selected by the
-               # leaf nodes of the first data structure.
-               #
-               # As the tree is traversed, an accumulator is kept.  This
-               # accumulator counts the bits of the opcode consumed by the
-               # traversal.  When accumulator + M = B, where B is the
-               # maximum number of bits in an opcode, the traversal has
-               # reached a leaf node.  The traversal starts with the most
-               # significant bits and works down to the least significant
-               # bits.
-               #
-               # Creation of the tree is the most complicated part.  At
-               # each node the elements are divided into groups of 2^M
-               # elements.  The value of M selected is the smallest possible
-               # value where all of the groups are either empty or full, or
-               # the groups are a preset minimum size.  If all the children
-               # of a node are non-empty leaf nodes, the children are merged
-               # to create a single leaf node that replaces the parent.
-
-               tree = self.divide_group(0, 0)
-
-               print '/*****************************************************************/'
-               print '/* tree depth = %u */' % (tree[3])
-               print 'static const int_fast16_t %s_dispatch_tree[%u] = {' % (self.name_base, tree[2])
-               self.dump_tree(tree, 0, self.max_bits, 0, 1)
-               print '};\n'
-               
-               # After dumping the tree, dump the function lookup table.
-               
-               print 'static const void *%s_function_table[%u][2] = {' % (self.name_base, len(self.lookup_table))
-               index = 0
-               for func in self.lookup_table:
-                       opcode = func[0]
-                       name = func[1]
-                       name_swap = func[2]
-                       
-                       print '    /* [% 3u] = %5u */ {%s, %s},' % (index, opcode, name, name_swap)
-                       
-                       index += 1
-
-               print '};\n'
-               
-               if self.do_size_check:
-                       var_table = []
-
-                       print 'static const int_fast16_t %s_size_table[%u][2] = {' % (self.name_base, len(self.lookup_table))
-                       index = 0
-                       var_table = []
-                       for func in self.lookup_table:
-                               opcode = func[0]
-                               fixed = func[3]
-                               var = func[4]
-                               
-                               if var != "":
-                                       var_offset = "%2u" % (len(var_table))
-                                       var_table.append(var)
-                               else:
-                                       var_offset = "~0"
-
-                               print '    /* [%3u] = %5u */ {%3u, %s},' % (index, opcode, fixed, var_offset)
-                               index += 1
-
-                               
-                       print '};\n'
-
-
-                       print 'static const gl_proto_size_func %s_size_func_table[%u] = {' % (self.name_base, len(var_table))
-                       for func in var_table:
-                               print '   %s,' % (func)
-                       print '};\n'
-
-
-               print 'const struct __glXDispatchInfo %s_dispatch_info = {' % (self.name_base)
-               print '    %u,' % (self.max_bits)
-               print '    %s_dispatch_tree,' % (self.name_base)
-               print '    %s_function_table,' % (self.name_base)
-               if self.do_size_check:
-                       print '    %s_size_table,' % (self.name_base)
-                       print '    %s_size_func_table' % (self.name_base)
-               else:
-                       print '    NULL,'
-                       print '    NULL'
-               print '};\n'
-               return
+        for M in range(0, remaining_bits):
+            op_count = 1 << (remaining_bits - M);
+            child_count = 1 << M;
 
+            empty_children = 0
+            full_children = 0
+            for i in range(min_opcode, next_opcode, op_count):
+                used = 0
+                empty = 0
 
-class PrintGlxDispatchTables(glX_proto_common.glx_print_proto):
-       def __init__(self):
-               gl_XML.gl_print_base.__init__(self)
-               self.name = "glX_server_table.py (from Mesa)"
-               self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2005, 2006", "IBM")
-
-               self.rop_functions = function_table("Render", 1)
-               self.sop_functions = function_table("Single", 0)
-               self.vop_functions = function_table("VendorPriv", 0)
-               return
-
-
-       def printRealHeader(self):
-               print '#include <inttypes.h>'
-               print '#include "glxserver.h"'
-               print '#include "glxext.h"'
-               print '#include "indirect_dispatch.h"'
-               print '#include "indirect_reqsize.h"'
-               print '#include "g_disptab.h"'
-               print '#include "indirect_table.h"'
-               print ''
-               return
-
-
-       def printBody(self, api):
-               for f in api.functionIterateAll():
-                       if not f.ignore and f.vectorequiv == None:
-                               if f.glx_rop != 0:
-                                       self.rop_functions.append(f.glx_rop, f)
-                               if f.glx_sop != 0:
-                                       self.sop_functions.append(f.glx_sop, f)
-                               if f.glx_vendorpriv != 0:
-                                       self.vop_functions.append(f.glx_vendorpriv, f)
-
-               self.sop_functions.Print()
-               self.rop_functions.Print()
-               self.vop_functions.Print()
-               return
+                for j in range(i, i + op_count):
+                    if self.functions.has_key(j):
+                        used += 1;
+                    else:
+                        empty += 1;
 
 
-if __name__ == '__main__':
-       file_name = "gl_API.xml"
+                if empty == op_count:
+                    empty_children += 1
+
+                if used == op_count:
+                    full_children += 1
+
+            if (empty_children > 0) or (full_children == child_count) or (op_count <= self.min_op_count):
+                break
+
+
+        # If all the remaining bits are used by this node, as is the
+        # case when M is 0 or remaining_bits, the node is a leaf.
+
+        if (M == 0) or (M == remaining_bits):
+            return [remaining_bits, [], 0, 0]
+        else:
+            children = []
+            count = 1
+            depth = 1
+            all_children_are_nonempty_leaf_nodes = 1
+            for i in range(min_opcode, next_opcode, op_count):
+                n = self.divide_group(i, total + M)
 
-       try:
-               (args, trail) = getopt.getopt(sys.argv[1:], "f:m")
-       except Exception,e:
-               show_usage()
+                if not (n[1] == [] and not self.is_empty_leaf(i, n[0])):
+                    all_children_are_nonempty_leaf_nodes = 0
 
-       mode = "table_c"
-       for (arg,val) in args:
-               if arg == "-f":
-                       file_name = val
-               elif arg == "-m":
-                       mode = val
+                children.append(n)
+                count += n[2] + 1
 
-       if mode == "table_c":
-               printer = PrintGlxDispatchTables()
-       else:
-               show_usage()
+                if n[3] >= depth:
+                    depth = n[3] + 1
 
+            # If all of the child nodes are non-empty leaf nodes, pull
+            # them up and make this node a leaf.
 
-       api = gl_XML.parse_GL_API( file_name, glX_XML.glx_item_factory() )
+            if all_children_are_nonempty_leaf_nodes:
+                return [remaining_bits, [], 0, 0]
+            else:
+                return [M, children, count, depth]
 
 
-       printer.Print( api )
+    def is_empty_leaf(self, base_opcode, M):
+        for op in range(base_opcode, base_opcode + (1 << M)):
+            if self.functions.has_key(op):
+                return 0
+                break
+
+        return 1
+
+
+    def dump_tree(self, node, base_opcode, remaining_bits, base_entry, depth):
+        M = node[0]
+        children = node[1]
+        child_M = remaining_bits - M
+
+
+        # This actually an error condition.
+        if children == []:
+            return
+
+        print '    /* [%u] -> opcode range [%u, %u], node depth %u */' % (base_entry, base_opcode, base_opcode + (1 << remaining_bits), depth)
+        print '    %u,' % (M)
+
+        base_entry += (1 << M) + 1
+
+        child_index = base_entry
+        child_base_opcode = base_opcode
+        for child in children:
+            if child[1] == []:
+                if self.is_empty_leaf(child_base_opcode, child_M):
+                    print '    EMPTY_LEAF,'
+                else:
+                    # Emit the index of the next dispatch
+                    # function.  Then add all the
+                    # dispatch functions for this leaf
+                    # node to the dispatch function
+                    # lookup table.
+
+                    print '    LEAF(%u),' % (len(self.lookup_table))
+
+                    for op in range(child_base_opcode, child_base_opcode + (1 << child_M)):
+                        if self.functions.has_key(op):
+                            func = self.functions[op]
+                            size = func.command_fixed_length()
+
+                            if func.glx_rop != 0:
+                                size += 4
+
+                            size = ((size + 3) & ~3)
+
+                            if func.has_variable_size_request():
+                                size_name = "__glX%sReqSize" % (func.name)
+                            else:
+                                size_name = ""
+
+                            if func.glx_vendorpriv == op:
+                                func_name = func.glx_vendorpriv_names[0]
+                            else:
+                                func_name = func.name
+
+                            temp = [op, "__glXDisp_%s" % (func_name), "__glXDispSwap_%s" % (func_name), size, size_name]
+                        else:
+                            temp = [op, "NULL", "NULL", 0, ""]
+
+                        self.lookup_table.append(temp)
+            else:
+                print '    %u,' % (child_index)
+                child_index += child[2]
+
+            child_base_opcode += 1 << child_M
+
+        print ''
+
+        child_index = base_entry
+        for child in children:
+            if child[1] != []:
+                self.dump_tree(child, base_opcode, remaining_bits - M, child_index, depth + 1)
+                child_index += child[2]
+
+            base_opcode += 1 << (remaining_bits - M)
+
+
+    def Print(self):
+        # Each dispatch table consists of two data structures.
+        #
+        # The first structure is an N-way tree where the opcode for
+        # the function is the key.  Each node switches on a range of
+        # bits from the opcode.  M bits are extracted from the opcde
+        # and are used as an index to select one of the N, where
+        # N = 2^M, children.
+        #
+        # The tree is stored as a flat array.  The first value is the
+        # number of bits, M, used by the node.  For inner nodes, the
+        # following 2^M values are indexes into the array for the
+        # child nodes.  For leaf nodes, the followign 2^M values are
+        # indexes into the second data structure.
+        #
+        # If an inner node's child index is 0, the child is an empty
+        # leaf node.  That is, none of the opcodes selectable from
+        # that child exist.  Since most of the possible opcode space
+        # is unused, this allows compact data storage.
+        #
+        # The second data structure is an array of pairs of function
+        # pointers.  Each function contains a pointer to a protocol
+        # decode function and a pointer to a byte-swapped protocol
+        # decode function.  Elements in this array are selected by the
+        # leaf nodes of the first data structure.
+        #
+        # As the tree is traversed, an accumulator is kept.  This
+        # accumulator counts the bits of the opcode consumed by the
+        # traversal.  When accumulator + M = B, where B is the
+        # maximum number of bits in an opcode, the traversal has
+        # reached a leaf node.  The traversal starts with the most
+        # significant bits and works down to the least significant
+        # bits.
+        #
+        # Creation of the tree is the most complicated part.  At
+        # each node the elements are divided into groups of 2^M
+        # elements.  The value of M selected is the smallest possible
+        # value where all of the groups are either empty or full, or
+        # the groups are a preset minimum size.  If all the children
+        # of a node are non-empty leaf nodes, the children are merged
+        # to create a single leaf node that replaces the parent.
+
+        tree = self.divide_group(0, 0)
+
+        print '/*****************************************************************/'
+        print '/* tree depth = %u */' % (tree[3])
+        print 'static const int_fast16_t %s_dispatch_tree[%u] = {' % (self.name_base, tree[2])
+        self.dump_tree(tree, 0, self.max_bits, 0, 1)
+        print '};\n'
+
+        # After dumping the tree, dump the function lookup table.
+
+        print 'static const void *%s_function_table[%u][2] = {' % (self.name_base, len(self.lookup_table))
+        index = 0
+        for func in self.lookup_table:
+            opcode = func[0]
+            name = func[1]
+            name_swap = func[2]
+
+            print '    /* [% 3u] = %5u */ {%s, %s},' % (index, opcode, name, name_swap)
+
+            index += 1
+
+        print '};\n'
+
+        if self.do_size_check:
+            var_table = []
+
+            print 'static const int_fast16_t %s_size_table[%u][2] = {' % (self.name_base, len(self.lookup_table))
+            index = 0
+            var_table = []
+            for func in self.lookup_table:
+                opcode = func[0]
+                fixed = func[3]
+                var = func[4]
+
+                if var != "":
+                    var_offset = "%2u" % (len(var_table))
+                    var_table.append(var)
+                else:
+                    var_offset = "~0"
+
+                print '    /* [%3u] = %5u */ {%3u, %s},' % (index, opcode, fixed, var_offset)
+                index += 1
+
+
+            print '};\n'
+
+
+            print 'static const gl_proto_size_func %s_size_func_table[%u] = {' % (self.name_base, len(var_table))
+            for func in var_table:
+                print '   %s,' % (func)
+
+            print '};\n'
+
+
+        print 'const struct __glXDispatchInfo %s_dispatch_info = {' % (self.name_base)
+        print '    %u,' % (self.max_bits)
+        print '    %s_dispatch_tree,' % (self.name_base)
+        print '    %s_function_table,' % (self.name_base)
+        if self.do_size_check:
+            print '    %s_size_table,' % (self.name_base)
+            print '    %s_size_func_table' % (self.name_base)
+        else:
+            print '    NULL,'
+            print '    NULL'
+        print '};\n'
+        return
+
+
+class PrintGlxDispatchTables(glX_proto_common.glx_print_proto):
+    def __init__(self):
+        gl_XML.gl_print_base.__init__(self)
+        self.name = "glX_server_table.py (from Mesa)"
+        self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2005, 2006", "IBM")
+
+        self.rop_functions = function_table("Render", 1)
+        self.sop_functions = function_table("Single", 0)
+        self.vop_functions = function_table("VendorPriv", 0)
+        return
+
+
+    def printRealHeader(self):
+        print '#include <inttypes.h>'
+        print '#include "glxserver.h"'
+        print '#include "glxext.h"'
+        print '#include "indirect_dispatch.h"'
+        print '#include "indirect_reqsize.h"'
+        print '#include "indirect_table.h"'
+        print ''
+        return
+
+
+    def printBody(self, api):
+        for f in api.functionIterateAll():
+            if not f.ignore and f.vectorequiv == None:
+                if f.glx_rop != 0:
+                    self.rop_functions.append(f.glx_rop, f)
+                if f.glx_sop != 0:
+                    self.sop_functions.append(f.glx_sop, f)
+                if f.glx_vendorpriv != 0:
+                    self.vop_functions.append(f.glx_vendorpriv, f)
+
+        self.sop_functions.Print()
+        self.rop_functions.Print()
+        self.vop_functions.Print()
+        return
+
+
+def _parser():
+    """Parse arguments and return namespace."""
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-f',
+                        dest='filename',
+                        default='gl_API.xml',
+                        help='An XML file describing an API.')
+    return parser.parse_args()
+
+
+if __name__ == '__main__':
+    args = _parser()
+    printer = PrintGlxDispatchTables()
+    api = gl_XML.parse_GL_API(args.filename, glX_XML.glx_item_factory())
+
+    printer.Print(api)