229 lines
5.1 KiB
Python
229 lines
5.1 KiB
Python
from reg_modified import *
|
|
import xml.etree.ElementTree as et
|
|
from argparse import ArgumentParser
|
|
|
|
def gen_gles_header(spec, filename):
|
|
# Generates the GLES header, wrapping gl functions
|
|
# prototypes in ORCA_IMPORT() macro
|
|
|
|
gles2through31Pat = '2\.[0-9]|3\.[01]'
|
|
allVersions = '.*'
|
|
|
|
genOpts = CGeneratorOptions(
|
|
filename=filename,
|
|
apiname='gles2',
|
|
profile='common',
|
|
versions=gles2through31Pat,
|
|
emitversions=allVersions,
|
|
protectProto=False,
|
|
procMacro='ORCA_IMPORT')
|
|
|
|
reg = Registry()
|
|
tree = et.parse(spec)
|
|
reg.loadElementTree(tree)
|
|
|
|
gen = COutputGenerator()
|
|
reg.setGenerator(gen)
|
|
reg.apiGen(genOpts)
|
|
|
|
|
|
def get_bindgen_tag_for_type(typeName):
|
|
typeToTags = {
|
|
"void": "v",
|
|
|
|
"GLenum": "i",
|
|
"GLbitfield": "i",
|
|
|
|
"GLboolean": "i",
|
|
"GLbyte": "i",
|
|
"GLubyte": "i",
|
|
"GLchar": "i",
|
|
|
|
"GLshort": "i",
|
|
"GLushort": "i",
|
|
"GLhalf": "i",
|
|
"GLhalfARB": "i",
|
|
|
|
"GLuint": "i",
|
|
"GLint": "i",
|
|
"GLclampx": "i",
|
|
"GLsizei": "i",
|
|
"GLfixed": "i",
|
|
|
|
"GLuint64": "I",
|
|
"GLint64": "I",
|
|
"GLintptr": "I",
|
|
"GLsizeiptr": "I",
|
|
|
|
"GLfloat": "f",
|
|
"GLclampf": "f",
|
|
|
|
"GLdouble": "F",
|
|
"GLclampd": "F",
|
|
|
|
"GLsync": "p"
|
|
}
|
|
|
|
if typeName[len(typeName)-1] == '*':
|
|
return "p"
|
|
else:
|
|
tag = typeToTags.get(typeName)
|
|
return tag
|
|
|
|
def gen_gles_bindgen_json(spec, filename):
|
|
|
|
# Gather gles 3.1 required functions
|
|
tree = et.parse(spec)
|
|
api = []
|
|
|
|
for feature in tree.iterfind('feature[@api="gles2"]'):
|
|
if float(feature.get('number')) > 3.1:
|
|
break
|
|
|
|
for require in feature.iter('require'):
|
|
if require.get('profile') == 'compatibility':
|
|
continue
|
|
for command in require.iter('command'):
|
|
api.append(command.get('name'))
|
|
|
|
for remove in feature.iter('remove'):
|
|
for command in remove.iter('command'):
|
|
api.remove(command.get('name'))
|
|
|
|
# put all GL commands in a dict
|
|
commands = dict()
|
|
commandsSpec = tree.find('./commands')
|
|
for command in commandsSpec.iter('command'):
|
|
name = command.find('proto/name')
|
|
commands[name.text] = command
|
|
|
|
# TODO: Generate json descriptions for commands in api
|
|
|
|
manualBind = [
|
|
"glShaderSource"]
|
|
|
|
json = '[\n'
|
|
for name in api:
|
|
if name in manualBind:
|
|
continue
|
|
|
|
command = commands.get(name)
|
|
if command == None:
|
|
print("Couldn't find definition for required command '" + name + "'")
|
|
exit(-1)
|
|
|
|
proto = command.find("proto")
|
|
ptype = proto.find("ptype")
|
|
|
|
retType = ''
|
|
if proto.text != None:
|
|
retType += proto.text
|
|
|
|
if ptype != None:
|
|
if ptype.text != None:
|
|
retType += ptype.text
|
|
if ptype.tail != None:
|
|
retType += ptype.tail
|
|
|
|
retType = retType.strip()
|
|
|
|
retTag = get_bindgen_tag_for_type(retType)
|
|
if retTag == None:
|
|
print("Couldn't find tag for GL type '" + retType + "'")
|
|
exit(-1)
|
|
|
|
entry = '{\n\t"name": "' + name + '",\n'
|
|
entry += '\t"cname": "' + name + '",\n'
|
|
entry += '\t"ret": { "name": "' + retType + '", "tag": "' + retTag + '"},\n'
|
|
|
|
entry += '\t"args": [ '
|
|
|
|
# iterate through params
|
|
for param in command.iter('param'):
|
|
|
|
argNode = param.find('name')
|
|
argName = argNode.text
|
|
|
|
typeNode = param.find('ptype')
|
|
|
|
typeName = ''
|
|
|
|
if param.text != None:
|
|
typeName += param.text
|
|
|
|
if typeNode != None:
|
|
if typeNode.text != None:
|
|
typeName += typeNode.text
|
|
if typeNode.tail != None:
|
|
typeName += typeNode.tail
|
|
|
|
typeName = typeName.strip()
|
|
|
|
typeTag = get_bindgen_tag_for_type(typeName)
|
|
|
|
if typeTag == None:
|
|
print("Couldn't find tag for GL type '" + typeName + "' in function '"+ name +"'")
|
|
exit(-1)
|
|
|
|
entry += '\n'
|
|
entry += '\t\t{"name": "'+ argName +'",\n'
|
|
entry += '\t\t "type": {"name": "'+ typeName +'", "tag": "'+ typeTag +'"}'
|
|
|
|
if param.get('len') != None:
|
|
lenString = param.get('len')
|
|
tokens = lenString.split('*')
|
|
|
|
if lenString.startswith("COMPSIZE"):
|
|
print("Warning: function " + name + ": parameter " + argName + " lenght uses COMPSIZE")
|
|
else:
|
|
entry += ',\n'
|
|
entry += '\t\t "len": {'
|
|
if len(tokens) == 2:
|
|
if tokens[1].isnumeric() == False:
|
|
print("Warning: function " + name + ": couldn't parse parameter '" + argName + "' lenght attribute")
|
|
entry += '"count": "' + tokens[0] + '", "components": "'+ tokens[1] + '"'
|
|
elif len(tokens) == 1:
|
|
if tokens[0].isnumeric():
|
|
entry += '"components":'+ tokens[0]
|
|
else:
|
|
entry += '"count": "'+ tokens[0] + '"'
|
|
else:
|
|
print("Warning: function " + name + ": couldn't parse parameter '" + argName + "' lenght attribute")
|
|
|
|
entry += '}'
|
|
elif typeTag == "p":
|
|
print("Warning: function " + name + ": parameter " + argName + " has no len attribute")
|
|
|
|
entry += '},'
|
|
|
|
entry = entry[:-1]
|
|
entry += '\n\t]\n}'
|
|
|
|
json += entry
|
|
json += ',\n'
|
|
|
|
json = json[:-2]
|
|
json += '\n]'
|
|
|
|
# write json to jsonFile
|
|
f = open(filename, 'w')
|
|
f.write(json)
|
|
f.close()
|
|
|
|
#----------------------------------------
|
|
# driver
|
|
#----------------------------------------
|
|
|
|
parser = ArgumentParser()
|
|
parser.add_argument("-s", "--spec")
|
|
parser.add_argument("--header")
|
|
parser.add_argument("-j", "--json")
|
|
|
|
args = parser.parse_args()
|
|
|
|
glesHeader = args.header
|
|
jsonFile = args.json
|
|
|
|
gen_gles_header(args.spec, glesHeader)
|
|
gen_gles_bindgen_json(args.spec, jsonFile)
|