From 0c1a7bbe0d0c6727a432890164032188787e7e26 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Sun, 22 Nov 2009 20:09:06 +0800 Subject: mesa/es: Add APIspec.xml and its parser. APIspec.xml is based on APIspec.txt. The new format has less code duplications and should be easier to read. Signed-off-by: Chia-I Wu --- src/mesa/es/main/APIspec.py | 601 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 601 insertions(+) create mode 100644 src/mesa/es/main/APIspec.py (limited to 'src/mesa/es/main/APIspec.py') diff --git a/src/mesa/es/main/APIspec.py b/src/mesa/es/main/APIspec.py new file mode 100644 index 0000000000..f07e4261fa --- /dev/null +++ b/src/mesa/es/main/APIspec.py @@ -0,0 +1,601 @@ +#!/usr/bin/python +# +# Copyright (C) 2009 Chia-I Wu +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# on the rights to use, copy, modify, merge, publish, distribute, sub +# license, and/or sell copies of the Software, and to permit persons to whom +# the Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +""" +A parser for APIspec. +""" + +class SpecError(Exception): + """Error in the spec file.""" + + +class Spec(object): + """A Spec is an abstraction of the API spec.""" + + def __init__(self, doc): + self.doc = doc + + self.spec_node = doc.getRootElement() + self.tmpl_nodes = {} + self.api_nodes = {} + self.impl_node = None + + # parse + node = self.spec_node.children + while node: + if node.type == "element": + if node.name == "template": + self.tmpl_nodes[node.prop("name")] = node + elif node.name == "api": + self.api_nodes[node.prop("name")] = node + else: + raise SpecError("unexpected node %s in apispec" % + node.name) + node = node.next + + # find an implementation + for name, node in self.api_nodes.iteritems(): + if node.prop("implementation") == "true": + self.impl_node = node + break + if not self.impl_node: + raise SpecError("unable to find an implementation") + + def get_impl(self): + """Return the implementation.""" + return API(self, self.impl_node) + + def get_api(self, name): + """Return an API.""" + return API(self, self.api_nodes[name]) + + +class API(object): + """An API consists of categories and functions.""" + + def __init__(self, spec, api_node): + self.name = api_node.prop("name") + self.is_impl = (api_node.prop("implementation") == "true") + + self.categories = [] + self.functions = [] + + # parse + func_nodes = [] + node = api_node.children + while node: + if node.type == "element": + if node.name == "category": + cat = node.prop("name") + self.categories.append(cat) + elif node.name == "function": + func_nodes.append(node) + else: + raise SpecError("unexpected node %s in api" % node.name) + node = node.next + + # realize functions + for func_node in func_nodes: + tmpl_node = spec.tmpl_nodes[func_node.prop("template")] + try: + func = Function(tmpl_node, func_node, self.is_impl, + self.categories) + except SpecError, e: + func_name = func_node.prop("name") + raise SpecError("failed to parse %s: %s" % (func_name, e)) + self.functions.append(func) + + def match(self, func, conversions={}): + """Find a matching function in the API.""" + match = None + need_conv = False + for f in self.functions: + matched, conv = f.match(func, conversions) + if matched: + match = f + need_conv = conv + # exact match + if not need_conv: + break + return (match, need_conv) + + +class Function(object): + """Parse and realize a @@ -3674,8 +3679,6 @@ - - diff --git a/src/mesa/es/main/APIspecutil.py b/src/mesa/es/main/APIspecutil.py index 5bfb699ba7..27a8fe8a6d 100644 --- a/src/mesa/es/main/APIspecutil.py +++ b/src/mesa/es/main/APIspecutil.py @@ -59,8 +59,11 @@ def _ParseXML(filename, apiname): for func in api.functions: alias, need_conv = impl.match(func, conversions) if not alias: - print >>sys.stderr, "Error: unable to dispatch %s" % func.name + # external functions are manually dispatched + if not func.is_external: + print >>sys.stderr, "Error: unable to dispatch %s" % func.name alias = func + need_conv = False __functions[func.name] = func __aliases[func.name] = (alias, need_conv) diff --git a/src/mesa/es/main/es_cpaltex.c b/src/mesa/es/main/es_cpaltex.c index 0d6f7410c3..15b6ad3617 100644 --- a/src/mesa/es/main/es_cpaltex.c +++ b/src/mesa/es/main/es_cpaltex.c @@ -19,7 +19,7 @@ #include "GLES/glext.h" -void GL_APIENTRY _es_CompressedTexImage2D(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +void GL_APIENTRY _es_CompressedTexImage2DARB(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); void GL_APIENTRY _mesa_TexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); void GL_APIENTRY _mesa_CompressedTexImage2DARB(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); @@ -215,9 +215,9 @@ cpal_compressed_teximage2d(GLenum target, GLint level, void GL_APIENTRY -_es_CompressedTexImage2D(GLenum target, GLint level, GLenum internalFormat, - GLsizei width, GLsizei height, GLint border, - GLsizei imageSize, const GLvoid *data) +_es_CompressedTexImage2DARB(GLenum target, GLint level, GLenum internalFormat, + GLsizei width, GLsizei height, GLint border, + GLsizei imageSize, const GLvoid *data) { switch (internalFormat) { case GL_PALETTE4_RGB8_OES: diff --git a/src/mesa/es/main/es_fbo.c b/src/mesa/es/main/es_fbo.c index 545c46ca99..db53a1449f 100644 --- a/src/mesa/es/main/es_fbo.c +++ b/src/mesa/es/main/es_fbo.c @@ -10,14 +10,14 @@ #include "GLES2/gl2ext.h" -extern void GL_APIENTRY _es_RenderbufferStorage(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height); +extern void GL_APIENTRY _es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height); extern void GL_APIENTRY _mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height); void GL_APIENTRY -_es_RenderbufferStorage(GLenum target, GLenum internalFormat, - GLsizei width, GLsizei height) +_es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat, + GLsizei width, GLsizei height) { switch (internalFormat) { case GL_RGBA4: diff --git a/src/mesa/es/main/es_generator.py b/src/mesa/es/main/es_generator.py index 349e0faa35..590f5940a7 100644 --- a/src/mesa/es/main/es_generator.py +++ b/src/mesa/es/main/es_generator.py @@ -272,7 +272,13 @@ for funcName in keys: # We're allowed to override the prefix and/or the function name # for each function record, though. The "ConversionFunction" # utility is poorly named, BTW... - aliasprefix = apiutil.AliasPrefix(funcName) + if funcName in allSpecials: + # perform checks and pass through + funcPrefix = "_check_" + aliasprefix = "_es_" + else: + funcPrefix = "_es_" + aliasprefix = apiutil.AliasPrefix(funcName) alias = apiutil.ConversionFunction(funcName) if not alias: # There may still be a Mesa alias for the function @@ -562,8 +568,9 @@ for funcName in keys: # The Mesa functions are scattered across all the Mesa # header files. The easiest way to manage declarations # is to create them ourselves. - if funcName not in allSpecials: - print "extern %s GLAPIENTRY %s(%s);" % (returnType, passthroughFuncName, passthroughDeclarationString) + if funcName in allSpecials: + print "/* this function is special and is defined elsewhere */" + print "extern %s GLAPIENTRY %s(%s);" % (returnType, passthroughFuncName, passthroughDeclarationString) # A function may be a core function (i.e. it exists in # the core specification), a core addition (extension @@ -594,22 +601,25 @@ for funcName in keys: if len(compoundCategory) == 1: # This is a core function extensionName = None - fullFuncName = "_es_" + funcName + extensionSuffix = "" else: # This is an extension function. We'll need to append # the extension suffix. extensionName = compoundCategory[1] extensionSuffix = extensionName.split("_")[0] - fullFuncName = "_es_" + funcName + extensionSuffix + fullFuncName = funcPrefix + funcName + extensionSuffix # Now the generated function. The text used to mark an API-level # function, oddly, is version-specific. if extensionName: print "/* Extension %s */" % extensionName - if funcName in allSpecials: - print "/* this function is special and is defined elsewhere */" - print "extern %s %s(%s);" % (returnType, fullFuncName, declarationString) + if (not variables and + not switchCode and + not conversionCodeOutgoing and + not conversionCodeIncoming): + # pass through directly + print "#define %s %s" % (fullFuncName, passthroughFuncName) print continue @@ -661,6 +671,7 @@ print "void" print "_mesa_init_exec_table(struct _glapi_table *exec)" print "{" for func in keys: + prefix = "_es_" if func not in allSpecials else "_check_" for spec in apiutil.Categories(func): ext = spec.split(":") # version does not match @@ -670,5 +681,5 @@ for func in keys: if ext: suffix = ext[0].split("_")[0] entry += suffix - print " SET_%s(exec, _es_%s);" % (entry, entry) + print " SET_%s(exec, %s%s);" % (entry, prefix, entry) print "}" -- cgit v1.2.3