aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/glapi/glX_XML.py
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2005-06-21 23:42:43 +0000
committerIan Romanick <[email protected]>2005-06-21 23:42:43 +0000
commit66a5548fbbf4c04a74b0bbc451718a8fc95502d9 (patch)
treef0e5a5964bca25e1e48c62bdb09e7f4c2fb88ce1 /src/mesa/glapi/glX_XML.py
parentf292e13a20a262411360bf4af5337595976cebc7 (diff)
Mammoth update to the Python code generator scripts that live in
src/mesa/glapi. Basically, the scripts that did simple things (like gl_offsets.py) were simple, and the scripts that did more complicated things (like glX_proto_send.py) were getting progressively more and more out of control. So, I re-write the foundation classes on which everything is based. One problem with the existing code is that the division between the GL API database representation and the way the output code is generated was either blury or nonexistant. The new code somewhat follows the Model-View-Controller pattern, minus the Controller. There is a distinct set of classes that model the API data, and there is a distinct set of classes that generate code from that data. One big change is in the class that represents GL functions (was glFunction, is now gl_function). There used to be an instance of this calls for each function and for each alias to that function. For example, there was an instance for PointParameterivSGIS, PointParameterivEXT, PointParameterivARB, and PointParameteriv. In the new code, there is one instance. Each instance has a list of entrypoint names for the function. In the next revision, this will allow a couple useful things. The script will be able to verify that the parameters, return type, and GLX protocol for a function and all it's aliases match. It will also allow aliases to be represented in the XML more compactly. Instead of repeating all the information, an alias can be listed as: <function name="PointParameterivARB" alias="PointParameterivEXT"/> Because the data representation was changed, the order that the alias functions are processed by the scripts also changed. This accounts for at least 2,700 of the ~3,600 lines of diffs in the generated code. Most of the remaining ~900 lines of diffs are the result of bugs *fixed* by the new scripts. The old scripts also generated code with some bugs in it. These bugs were discovered while the new code was being written. These changes were discussed on the mesa3d-dev mailing list back at the end of May: http://marc.theaimsgroup.com/?t=111714569000004&r=1&w=2 Xorg bug: 3197, 3208
Diffstat (limited to 'src/mesa/glapi/glX_XML.py')
-rw-r--r--src/mesa/glapi/glX_XML.py782
1 files changed, 298 insertions, 484 deletions
diff --git a/src/mesa/glapi/glX_XML.py b/src/mesa/glapi/glX_XML.py
index 53f89b31bd5..e0f07e576e4 100644
--- a/src/mesa/glapi/glX_XML.py
+++ b/src/mesa/glapi/glX_XML.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python2
+#!/usr/bin/env python
# (C) Copyright IBM Corporation 2004, 2005
# All Rights Reserved.
@@ -30,437 +30,319 @@ import license
import sys, getopt, string
-class glXItemFactory(gl_XML.glItemFactory):
- """Factory to create GLX protocol oriented objects derived from glItem."""
+class glx_item_factory(gl_XML.gl_item_factory):
+ """Factory to create GLX protocol oriented objects derived from gl_item."""
- def create(self, context, name, attrs):
+ def create_item(self, name, element, context):
if name == "function":
- return glXFunction(context, name, attrs)
+ return glx_function(element, context)
elif name == "enum":
- return glXEnum(context, name, attrs)
- elif name == "param":
- return glXParameter(context, name, attrs)
+ return glx_enum(element, context)
+ elif name == "api":
+ return glx_api(self)
else:
- return gl_XML.glItemFactory.create(self, context, name, attrs)
+ return gl_XML.gl_item_factory.create_item(self, name, element, context)
-class glXEnumFunction:
- def __init__(self, name, context):
- self.name = name
- self.context = context
- self.mode = 0
- self.sig = None
- # "enums" is a set of lists. The element in the set is the
- # value of the enum. The list is the list of names for that
- # value. For example, [0x8126] = {"POINT_SIZE_MIN",
- # "POINT_SIZE_MIN_ARB", "POINT_SIZE_MIN_EXT",
- # "POINT_SIZE_MIN_SGIS"}.
-
- self.enums = {}
-
- # "count" is indexed by count values. Each element of count
- # is a list of index to "enums" that have that number of
- # associated data elements. For example, [4] =
- # {GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_EMISSION,
- # GL_AMBIENT_AND_DIFFUSE} (the enum names are used here,
- # but the actual hexadecimal values would be in the array).
-
- self.count = {}
-
-
- def append(self, count, value, name):
- if self.enums.has_key( value ):
- self.enums[value].append(name)
- else:
- if not self.count.has_key(count):
- self.count[count] = []
-
- self.enums[value] = []
- self.enums[value].append(name)
- self.count[count].append(value)
-
-
- def signature( self ):
- if self.sig == None:
- self.sig = ""
- for i in self.count:
- self.count[i].sort()
- for e in self.count[i]:
- self.sig += "%04x,%u," % (e, i)
-
- return self.sig
-
-
- def set_mode( self, mode ):
- """Mark an enum-function as a 'set' function."""
-
- self.mode = mode
-
-
- def is_set( self ):
- return self.mode
-
-
- def PrintUsingTable(self):
- """Emit the body of the __gl*_size function using a pair
- of look-up tables and a mask. The mask is calculated such
- that (e & mask) is unique for all the valid values of e for
- this function. The result of (e & mask) is used as an index
- into the first look-up table. If it matches e, then the
- same entry of the second table is returned. Otherwise zero
- is returned.
+class glx_enum(gl_XML.gl_enum):
+ def __init__(self, element, context):
+ gl_XML.gl_enum.__init__(self, element, context)
- It seems like this should cause better code to be generated.
- However, on x86 at least, the resulting .o file is about 20%
- larger then the switch-statment version. I am leaving this
- code in because the results may be different on other
- platforms (e.g., PowerPC or x86-64)."""
-
- return 0
- count = 0
- for a in self.enums:
- count += 1
-
- if self.count.has_key(-1):
- return 0
-
- # Determine if there is some mask M, such that M = (2^N) - 1,
- # that will generate unique values for all of the enums.
+ self.functions = {}
+
+ child = element.children
+ while child:
+ if child.type == "element" and child.name == "size":
+ n = child.nsProp( "name", None )
+ c = child.nsProp( "count", None )
+ m = child.nsProp( "mode", None )
+
+ if not c:
+ c = self.default_count
+
+ if m == "get":
+ mode = 0
+ else:
+ mode = 1
- mask = 0
- for i in [1, 2, 3, 4, 5, 6, 7, 8]:
- mask = (1 << i) - 1
+ if not self.functions.has_key(n):
+ self.functions[ n ] = [c, mode]
- fail = 0;
- for a in self.enums:
- for b in self.enums:
- if a != b:
- if (a & mask) == (b & mask):
- fail = 1;
+ child = child.next
- if not fail:
- break;
- else:
- mask = 0
+ return
- if (mask != 0) and (mask < (2 * count)):
- masked_enums = {}
- masked_count = {}
- for i in range(0, mask + 1):
- masked_enums[i] = "0";
- masked_count[i] = 0;
+class glx_function(gl_XML.gl_function):
+ def __init__(self, element, context):
+ self.glx_rop = 0
+ self.glx_sop = 0
+ self.glx_vendorpriv = 0
- for c in self.count:
- for e in self.count[c]:
- i = e & mask
- masked_enums[i] = '0x%04x /* %s */' % (e, self.enums[e][0])
- masked_count[i] = c
+ # If this is set to true, it means that GLdouble parameters should be
+ # written to the GLX protocol packet in the order they appear in the
+ # prototype. This is different from the "classic" ordering. In the
+ # classic ordering GLdoubles are written to the protocol packet first,
+ # followed by non-doubles. NV_vertex_program was the first extension
+ # to break with this tradition.
+ self.glx_doubles_in_order = 0
- print ' static const GLushort a[%u] = {' % (mask + 1)
- for e in masked_enums:
- print ' %s, ' % (masked_enums[e])
- print ' };'
+ self.vectorequiv = None
+ self.output = None
+ self.can_be_large = 0
+ self.reply_always_array = 0
+ self.dimensions_in_reply = 0
+ self.img_reset = None
- print ' static const GLubyte b[%u] = {' % (mask + 1)
- for c in masked_count:
- print ' %u, ' % (masked_count[c])
- print ' };'
+ self.server_handcode = 0
+ self.client_handcode = 0
+ self.ignore = 0
- print ' const unsigned idx = (e & 0x%02xU);' % (mask)
- print ''
- print ' return (e == a[idx]) ? (GLint) b[idx] : 0;'
- return 1;
- else:
- return 0;
+ self.count_parameter_list = []
+ self.counter_list = []
+ self.parameters_by_name = {}
+ self.offsets_calculated = 0
- def PrintUsingSwitch(self, name):
- """Emit the body of the __gl*_size function using a
- switch-statement."""
+ gl_XML.gl_function.__init__(self, element, context)
+ return
- print ' switch( e ) {'
- for c in self.count:
- for e in self.count[c]:
- first = 1
+ def process_element(self, element):
+ gl_XML.gl_function.process_element(self, element)
- # There may be multiple enums with the same
- # value. This happens has extensions are
- # promoted from vendor-specific or EXT to
- # ARB and to the core. Emit the first one as
- # a case label, and emit the others as
- # commented-out case labels.
+ self.vectorequiv = element.nsProp( "vectorequiv", None )
- for j in self.enums[e]:
- if first:
- print ' case %s:' % (j)
- first = 0
- else:
- print '/* case %s:*/' % (j)
-
- if c == -1:
- print ' return __gl%s_variable_size( e );' % (name)
- else:
- print ' return %u;' % (c)
-
- print ' default: return 0;'
- print ' }'
+ if element.nsProp( "name", None ) == self.name:
+ for param in self.parameters:
+ self.parameters_by_name[ param.name ] = param
+
+ if len(param.count_parameter_list):
+ self.count_parameter_list.extend( param.count_parameter_list )
+
+ if param.counter and param.counter not in self.counter_list:
+ self.counter_list.append(param.counter)
- def Print(self, name):
- print 'INTERNAL PURE FASTCALL GLint'
- print '__gl%s_size( GLenum e )' % (name)
- print '{'
- if not self.PrintUsingTable():
- self.PrintUsingSwitch(name)
+ child = element.children
+ while child:
+ if child.type == "element":
+ if child.name == "glx":
+ rop = child.nsProp( 'rop', None )
+ sop = child.nsProp( 'sop', None )
+ vop = child.nsProp( 'vendorpriv', None )
- print '}'
- print ''
+ if rop:
+ self.glx_rop = int(rop)
+ else:
+ self.glx_rop = 0
+ if sop:
+ self.glx_sop = int(sop)
+ else:
+ self.glx_sop = 0
+ if vop:
+ self.glx_vendorpriv = int(vop)
+ else:
+ self.glx_vendorpriv = 0
+
+ self.img_reset = child.nsProp( 'img_reset', None )
+
+ # The 'handcode' attribute can be one of 'true',
+ # 'false', 'client', or 'server'.
+
+ handcode = child.nsProp( 'handcode', None )
+ if handcode == "false":
+ self.server_handcode = 0
+ self.client_handcode = 0
+ elif handcode == "true":
+ self.server_handcode = 1
+ self.client_handcode = 1
+ elif handcode == "client":
+ self.server_handcode = 0
+ self.client_handcode = 1
+ elif handcode == "server":
+ self.server_handcode = 1
+ self.client_handcode = 0
+ else:
+ raise RuntimeError('Invalid handcode mode "%s" in function "%s".' % (handcode, self.name))
-class glXEnum(gl_XML.glEnum):
- def __init__(self, context, name, attrs):
- gl_XML.glEnum.__init__(self, context, name, attrs)
+ self.ignore = gl_XML.is_attr_true( child, 'ignore' )
+ self.can_be_large = gl_XML.is_attr_true( child, 'large' )
+ self.glx_doubles_in_order = gl_XML.is_attr_true( child, 'doubles_in_order' )
+ self.reply_always_array = gl_XML.is_attr_true( child, 'always_array' )
+ self.dimensions_in_reply = gl_XML.is_attr_true( child, 'dimensions_in_reply' )
+ child = child.next
- def startElementNS(self, name, qname, attrs):
- [uri, true_name] = name
- if true_name == "size":
- [temp_n, c, mode] = self.process_attributes(attrs)
- if temp_n == "Get":
- names = ["GetIntegerv", "GetBooleanv", "GetFloatv", "GetDoublev" ]
- else:
- names = [ temp_n ]
+ # Do some validation of the GLX protocol information. As
+ # new tests are discovered, they should be added here.
- for n in names:
- if not self.context.glx_enum_functions.has_key( n ):
- f = self.context.createEnumFunction( n )
- f.set_mode( mode )
- self.context.glx_enum_functions[ f.name ] = f
+ for param in self.parameters:
+ if param.is_output and self.glx_rop != 0:
+ raise RuntimeError("Render / RenderLarge commands cannot have outputs (%s)." % (self.name))
- self.context.glx_enum_functions[ n ].append( c, self.value, self.name )
- else:
- gl_XML.glEnum.startElementNS(self, name, qname, attrs)
return
-class glXParameter(gl_XML.glParameter):
- def __init__(self, context, name, attrs):
- self.order = 1;
- gl_XML.glParameter.__init__(self, context, name, attrs);
-
-
-class glXParameterIterator:
- """Class to iterate over a list of glXParameters.
-
- Objects of this class are returned by the parameterIterator method of
- the glXFunction class. They are used to iterate over the list of
- parameters to the function."""
-
- def __init__(self, data, skip_output, max_order):
- self.data = data
- self.index = 0
- self.order = 0
- self.skip_output = skip_output
- self.max_order = max_order
-
- def __iter__(self):
- return self
-
- def next(self):
- if len( self.data ) == 0:
- raise StopIteration
-
- while 1:
- if self.index == len( self.data ):
- if self.order == self.max_order:
- raise StopIteration
- else:
- self.order += 1
- self.index = 0
-
- i = self.index
- self.index += 1
-
- if self.data[i].order == self.order and not (self.data[i].is_output and self.skip_output):
- return self.data[i]
+ def has_variable_size_request(self):
+ """Determine if the GLX request packet is variable sized.
+ The GLX request packet is variable sized in several common
+ situations.
+
+ 1. The function has a non-output parameter that is counted
+ by another parameter (e.g., the 'textures' parameter of
+ glDeleteTextures).
+
+ 2. The function has a non-output parameter whose count is
+ determined by another parameter that is an enum (e.g., the
+ 'params' parameter of glLightfv).
+
+ 3. The function has a non-output parameter that is an
+ image.
+
+ 4. The function must be hand-coded on the server.
+ """
+
+ if self.glx_rop == 0:
+ return 0
-class glXFunction(gl_XML.glFunction):
- glx_rop = 0
- glx_sop = 0
- glx_vendorpriv = 0
+ if self.server_handcode or self.images:
+ return 1
- # If this is set to true, it means that GLdouble parameters should be
- # written to the GLX protocol packet in the order they appear in the
- # prototype. This is different from the "classic" ordering. In the
- # classic ordering GLdoubles are written to the protocol packet first,
- # followed by non-doubles. NV_vertex_program was the first extension
- # to break with this tradition.
+ for param in self.parameters:
+ if not param.is_output:
+ if param.counter or len(param.count_parameter_list):
+ return 1
- glx_doubles_in_order = 0
+ return 0
- vectorequiv = None
- can_be_large = 0
- def __init__(self, context, name, attrs):
- self.vectorequiv = attrs.get((None, 'vectorequiv'), None)
- self.counter = None
- self.output = None
- self.can_be_large = 0
- self.reply_always_array = 0
- self.dimensions_in_reply = 0
- self.img_reset = None
+ def variable_length_parameter(self):
+ for param in self.parameters:
+ if not param.is_output:
+ if param.counter or len(param.count_parameter_list):
+ return param
+
+ return None
- self.server_handcode = 0
- self.client_handcode = 0
- self.ignore = 0
- gl_XML.glFunction.__init__(self, context, name, attrs)
- return
+ def calculate_offsets(self):
+ if not self.offsets_calculated:
+ # Calculate the offset of the first function parameter
+ # in the GLX command packet. This byte offset is
+ # measured from the end of the Render / RenderLarge
+ # header. The offset for all non-pixel commends is
+ # zero. The offset for pixel commands depends on the
+ # number of dimensions of the pixel data.
+ if len(self.images) and not self.images[0].is_output:
+ [dim, junk, junk, junk, junk] = self.images[0].get_dimensions()
- def parameterIterator(self, skip_output, max_order):
- return glXParameterIterator(self.fn_parameters, skip_output, max_order)
+ # The base size is the size of the pixel pack info
+ # header used by images with the specified number
+ # of dimensions.
-
- def startElementNS(self, name, qname, attrs):
- """Process elements within a function that are specific to GLX."""
-
- [uri, true_name] = name
- if true_name == "glx":
- self.glx_rop = int(attrs.get((None, 'rop'), "0"))
- self.glx_sop = int(attrs.get((None, 'sop'), "0"))
- self.glx_vendorpriv = int(attrs.get((None, 'vendorpriv'), "0"))
- self.img_reset = attrs.get((None, 'img_reset'), None)
-
- # The 'handcode' attribute can be one of 'true',
- # 'false', 'client', or 'server'.
-
- handcode = attrs.get((None, 'handcode'), "false")
- if handcode == "false":
- self.server_handcode = 0
- self.client_handcode = 0
- elif handcode == "true":
- self.server_handcode = 1
- self.client_handcode = 1
- elif handcode == "client":
- self.server_handcode = 0
- self.client_handcode = 1
- elif handcode == "server":
- self.server_handcode = 1
- self.client_handcode = 0
+ if dim <= 2:
+ offset = 20
+ elif dim <= 4:
+ offset = 36
+ else:
+ raise RuntimeError('Invalid number of dimensions %u for parameter "%s" in function "%s".' % (dim, self.image.name, self.name))
else:
- raise RuntimeError('Invalid handcode mode "%s" in function "%s".' % (handcode, self.name))
-
- self.ignore = gl_XML.is_attr_true( attrs, 'ignore' )
- self.can_be_large = gl_XML.is_attr_true( attrs, 'large' )
- self.glx_doubles_in_order = gl_XML.is_attr_true( attrs, 'doubles_in_order' )
- self.reply_always_array = gl_XML.is_attr_true( attrs, 'always_array' )
- self.dimensions_in_reply = gl_XML.is_attr_true( attrs, 'dimensions_in_reply' )
- else:
- gl_XML.glFunction.startElementNS(self, name, qname, attrs)
-
-
- def endElementNS(self, name, qname):
- [uri, true_name] = name
- if true_name == "function":
- # Mark any function that does not have GLX protocol
- # defined as "ignore". This prevents bad things from
- # happening when people add new functions to the GL
- # API XML without adding any GLX section.
- #
- # This will also mark functions that don't have a
- # dispatch offset at ignored.
-
- if (self.fn_offset == -1 and not self.fn_alias) or not (self.client_handcode or self.server_handcode or self.glx_rop or self.glx_sop or self.glx_vendorpriv or self.vectorequiv or self.fn_alias):
- #if not self.ignore:
- # if self.fn_offset == -1:
- # print '/* %s ignored becuase no offset assigned. */' % (self.name)
- # else:
- # print '/* %s ignored becuase no GLX opcode assigned. */' % (self.name)
+ offset = 0
- self.ignore = 1
+ for param in self.parameterIterateGlxSend():
+ if param.img_null_flag:
+ offset += 4
- return gl_XML.glFunction.endElementNS(self, name, qname)
-
-
- def append(self, tag_name, p):
- gl_XML.glFunction.append(self, tag_name, p)
-
- if p.is_variable_length_array():
- p.order = 2;
- elif not self.glx_doubles_in_order and p.p_type.size == 8:
- p.order = 0;
+ if param.name != self.img_reset:
+ param.offset = offset
+ if not param.is_variable_length():
+ offset += param.size()
+
+ if self.pad_after( param ):
+ offset += 4
- if p.is_counter:
- self.counter = p.name
-
- if p.is_output:
- self.output = p
+ self.offsets_calculated = 1
return
- def variable_length_parameter(self):
- if len(self.variable_length_parameters):
- return self.variable_length_parameters[0]
+ def offset_of(self, param_name):
+ self.calculate_offsets()
+ return self.parameters_by_name[ param_name ].offset
- return None
+ def parameterIterateGlxSend(self, include_variable_parameters = 1):
+ """Create an iterator for parameters in GLX request order."""
- def output_parameter(self):
- for param in self.fn_parameters:
- if param.is_output:
- return param
+ # The parameter lists are usually quite short, so it's easier
+ # (i.e., less code) to just generate a new list with the
+ # required elements than it is to create a new iterator class.
+
+ temp = [ [], [], [] ]
+ for param in self.parameters:
+ if param.is_output: continue
+
+ if param.is_variable_length():
+ temp[2].append( param )
+ elif not self.glx_doubles_in_order and param.is_64_bit():
+ temp[0].append( param )
+ else:
+ temp[1].append( param )
- return None
+ parameters = temp[0]
+ parameters.extend( temp[1] )
+ if include_variable_parameters:
+ parameters.extend( temp[2] )
+ return parameters.__iter__()
- def offset_of_first_parameter(self):
- """Get the offset of the first parameter in the command.
+ def parameterIterateCounters(self):
+ temp = []
+ for name in self.counter_list:
+ temp.append( self.parameters_by_name[ name ] )
- Gets the offset of the first function parameter in the GLX
- command packet. This byte offset is measured from the end
- of the Render / RenderLarge header. The offset for all non-
- pixel commends is zero. The offset for pixel commands depends
- on the number of dimensions of the pixel data."""
+ return temp.__iter__()
- if self.image and not self.image.is_output:
- [dim, junk, junk, junk, junk] = self.dimensions()
- # The base size is the size of the pixel pack info
- # header used by images with the specified number
- # of dimensions.
+ def parameterIterateOutputs(self):
+ temp = []
+ for p in self.parameters:
+ if p.is_output:
+ temp.append( p )
- if dim <= 2:
- return 20
- elif dim <= 4:
- return 36
- else:
- raise RuntimeError('Invalid number of dimensions %u for parameter "%s" in function "%s".' % (dim, self.image.name, self.name))
- else:
- return 0
+ return temp
def command_fixed_length(self):
"""Return the length, in bytes as an integer, of the
fixed-size portion of the command."""
- size = self.offset_of_first_parameter()
+ if len(self.parameters) == 0:
+ return 0
+
+ self.calculate_offsets()
- for p in gl_XML.glFunction.parameterIterator(self):
- if not p.is_output and p.name != self.img_reset:
- size += p.size()
- if self.pad_after(p):
+ size = 0
+ for param in self.parameterIterateGlxSend(0):
+ if param.name != self.img_reset:
+ if size == 0:
+ size = param.offset + param.size()
+ else:
+ size += param.size()
+
+ if self.pad_after( param ):
size += 4
- if self.image and (self.image.img_null_flag or self.image.is_output):
- size += 4
+ for param in self.images:
+ if param.img_null_flag or param.is_output:
+ size += 4
return size
@@ -470,9 +352,15 @@ class glXFunction(gl_XML.glFunction):
portion of the command."""
size_string = ""
- for p in gl_XML.glFunction.parameterIterator(self):
- if (not p.is_output) and (p.size() == 0):
- size_string = size_string + " + __GLX_PAD(%s)" % (p.size_string())
+ for p in self.parameterIterateGlxSend():
+ if (not p.is_output) and (p.is_variable_length() or p.is_image()):
+ # FIXME Replace the 1 in the size_string call
+ # FIXME w/0 to eliminate some un-needed parnes
+ # FIXME This would already be done, but it
+ # FIXME adds some extra diffs to the generated
+ # FIXME code.
+
+ size_string = size_string + " + __GLX_PAD(%s)" % (p.size_string(1))
return size_string
@@ -506,9 +394,15 @@ class glXFunction(gl_XML.glFunction):
else:
return self.opcode_value()
+
def opcode_value(self):
"""Get the unique protocol opcode for the glXFunction"""
+ if (self.glx_rop == 0) and self.vectorequiv:
+ equiv = self.context.functions_by_name[ self.vectorequiv ]
+ self.glx_rop = equiv.glx_rop
+
+
if self.glx_rop != 0:
return self.glx_rop
elif self.glx_sop != 0:
@@ -518,6 +412,7 @@ class glXFunction(gl_XML.glFunction):
else:
return -1
+
def opcode_rop_basename(self):
"""Return either the name to be used for GLX protocol enum.
@@ -530,9 +425,16 @@ class glXFunction(gl_XML.glFunction):
else:
return self.vectorequiv
+
def opcode_name(self):
"""Get the unique protocol enum name for the glXFunction"""
+ if (self.glx_rop == 0) and self.vectorequiv:
+ equiv = self.context.functions_by_name[ self.vectorequiv ]
+ self.glx_rop = equiv.glx_rop
+ self.glx_doubles_in_order = equiv.glx_doubles_in_order
+
+
if self.glx_rop != 0:
return "X_GLrop_%s" % (self.opcode_rop_basename())
elif self.glx_sop != 0:
@@ -562,154 +464,66 @@ class glXFunction(gl_XML.glFunction):
return self.opcode_name()
- def return_string(self):
- if self.fn_return_type != 'void':
- return "return retval;"
- else:
- return "return;"
-
-
def needs_reply(self):
- return self.fn_return_type != 'void' or self.output != None
+ try:
+ x = self._needs_reply
+ except Exception, e:
+ x = 0
+ if self.return_type != 'void':
+ x = 1
+ for param in self.parameters:
+ if param.is_output:
+ x = 1
+ break
- def dimensions(self):
- """Determine the dimensions of an image.
-
- Returns a tuple representing the number of dimensions and the
- string name of each of the dimensions of an image, If the
- function is not a pixel function, the number of dimensions
- will be zero."""
-
- if not self.image:
- return [0, "0", "0", "0", "0"]
- else:
- dim = 1
- w = self.image.width
-
- if self.image.height:
- dim = 2
- h = self.image.height
- else:
- h = "1"
-
- if self.image.depth:
- dim = 3
- d = self.image.depth
- else:
- d = "1"
-
- if self.image.extent:
- dim = 4
- e = self.image.extent
- else:
- e = "1"
+ self._needs_reply = x
- return [dim, w, h, d, e]
+ return x
def pad_after(self, p):
"""Returns the name of the field inserted after the
specified field to pad out the command header."""
- if self.image and self.image.img_pad_dimensions:
- if not self.image.height:
- if p.name == self.image.width:
- return "height"
- elif p.name == self.image.img_xoff:
- return "yoffset"
- elif not self.image.extent:
- if p.name == self.image.depth:
- # Should this be "size4d"?
- return "extent"
- elif p.name == self.image.img_zoff:
- return "woffset"
+ for image in self.images:
+ if image.img_pad_dimensions:
+ if not image.height:
+ if p.name == image.width:
+ return "height"
+ elif p.name == image.img_xoff:
+ return "yoffset"
+ elif not image.extent:
+ if p.name == image.depth:
+ # Should this be "size4d"?
+ return "extent"
+ elif p.name == image.img_zoff:
+ return "woffset"
+
return None
-class glXFunctionIterator(gl_XML.glFunctionIterator):
+class glx_function_iterator:
"""Class to iterate over a list of glXFunctions"""
def __init__(self, context):
- self.context = context
- self.keys = context.functions.keys()
- self.keys.sort()
-
- for self.index in range(0, len(self.keys)):
- if self.keys[ self.index ] >= 0: break
-
+ self.iterator = context.functionIterateByOffset()
return
- def next(self):
- if self.index == len(self.keys):
- raise StopIteration
+ def __iter__(self):
+ return self
- f = self.context.functions[ self.keys[ self.index ] ]
- self.index += 1
- if f.ignore:
+ def next(self):
+ f = self.iterator.next()
+ if f.ignore or not (f.glx_rop or f.glx_sop or f.glx_vendorpriv or f.vectorequiv or f.client_handcode):
return self.next()
else:
return f
-class GlxProto(gl_XML.FilterGLAPISpecBase):
- name = "glX_proto_send.py (from Mesa)"
-
- def __init__(self):
- gl_XML.FilterGLAPISpecBase.__init__(self)
- self.factory = glXItemFactory()
- self.glx_enum_functions = {}
-
-
- def endElementNS(self, name, qname):
- [uri, true_name] = name
- if true_name == 'OpenGLAPI':
- # Once all the parsing is done, we have to go back and
- # fix-up some cross references between different
- # functions.
-
- for k in self.functions:
- f = self.functions[k]
- if f.vectorequiv != None:
- equiv = self.find_function(f.vectorequiv)
- if equiv != None:
- f.glx_doubles_in_order = equiv.glx_doubles_in_order
- f.glx_rop = equiv.glx_rop
- else:
- raise RuntimeError("Could not find the vector equiv. function %s for %s!" % (f.name, f.vectorequiv))
- else:
- gl_XML.FilterGLAPISpecBase.endElementNS(self, name, qname)
- return
-
-
- def createEnumFunction(self, n):
- return glXEnumFunction(n, self)
-
-
- def functionIterator(self):
- return glXFunctionIterator(self)
-
-
- def size_call(self, func):
- """Create C code to calculate 'compsize'.
-
- Creates code to calculate 'compsize'. If the function does
- not need 'compsize' to be calculated, None will be
- returned."""
-
- if not func.image and not func.count_parameter_list:
- return None
-
- if not func.image:
- parameters = string.join( func.count_parameter_list, "," )
- compsize = "__gl%s_size(%s)" % (func.name, parameters)
- else:
- [dim, w, h, d, junk] = func.dimensions()
-
- compsize = '__glImageSize(%s, %s, %s, %s, %s, %s)' % (w, h, d, func.image.img_format, func.image.img_type, func.image.img_target)
- if not func.image.img_send_null:
- compsize = '(%s != NULL) ? %s : 0' % (func.image.name, compsize)
+class glx_api(gl_XML.gl_api):
+ def functionIterateGlx(self):
+ return glx_function_iterator(self)
- return compsize