regal/scripts/Emu.py
Nigel Stewart ce35076e59 Apitrace updates, DSA fixes, NV_bindless_texture, NV_draw_texture, AMD_sparse_texture.
Regal gl.py fixups.
Initial build target support for wrangler-mode Regal.
GLEW refresh.
2013-11-22 15:02:03 -06:00

212 lines
5 KiB
Python

#!/usr/bin/python -B
#
# When tracing the driver side, all loader functions must have their proc addresses finalized
# so we can hijack the loadedTbl.
#
# void driver_entry( arg0, arg1, ... ) {
# if( layer_1 && layer_1_inactive ) {
# layer_1_activate
# layer_1_prefix
# layer_1_deactivate
# }
# if( layer_0 && layer_0_inactive ) {
# layer_0_activate
# layer_0_prefix
# layer_0_deactivate
# }
#
# if( layer_1 && layer_1_inactive ) {
# layer_1_activate
# layer_1_impl
# layer_1_deactivate
# } else if( layer_0 && layer_0_inactive ) {
# layer_0_activate
# layer_0_impl
# layer_0_deactivate
# } else {
# loaded.entry(...)
# }
# }
from ApiCodeGen import typeCode, wrapIf, wrapCIf
from ApiUtil import typeIsVoid
import re
from string import Template
from string import join
from copy import deepcopy
#
# Apply per-section substitutions
#
# Inputs:
#
# entry - the "emue" dictionary
# formula - formula dictionary
# section - section name
# subs - substitutions for string.Template.substitute
#
def substitute(entry, formula, section, subs):
if not section in formula:
return
# Turn a string into a list, if necessary
tmp = formula[section]
if isinstance(tmp,str) or isinstance(tmp,unicode):
tmp = tmp.split('\n')
entry[section] = [ Template(i).substitute(subs) for i in tmp ]
#
# Add a substitution for string.Template.substitute purposes
#
# Inputs:
#
# name - entry point name
# formula - formula dictionary
# subs - string.Template.substitute substitutions
#
# Outputs:
#
# updated subs
def addSubstitution(name, formula, subs):
if not 'subst' in formula:
return
s = deepcopy( subs )
for newdef in formula['subst'] :
dd = formula['subst'][newdef]
r = None
for k in dd :
m = re.match( '^%s$' % k, name )
if m :
r = dd[k]
#print 'matched! - result is %s' % r
break
if not r :
r = dd['default']
r = Template( r ).substitute( s )
subs[newdef]= r
#
# Inputs:
#
# func - Api function to match
# emuFormulae - Emulation formulae (list?)
# member - Name of the RegalContext member to check for not-NULL
#
# Output:
#
# A dictionary of stuff, the "emue"
# { 'name' : name, 'member' : member, 'impl' : { ... }, ... }
def emuFindEntry(func, emuFormulae, member, ifdef = None):
if emuFormulae==None:
return None
name = func.name
# list of function parameter names
arglist = [ i.name.strip() for i in func.parameters ]
# arg is a mapping from arg0 to function parameter name...
arg = {}
for i in range(len(arglist)):
arg['arg%d' % i] = arglist[i]
# ... and mappings from arg0plus to lists of function parameters
for i in range(0,5):
label = 'arg%dplus' % i;
if len(arglist) > 0 :
arg[label] = ', '.join(arglist)
arglist.pop(0)
else :
arg[label] = ''
# Iterator over the formulae
#
# k is the key
# i is the formula
for k,i in emuFormulae.iteritems():
# Cache the compiled regular expressions, as needed
if 'entries_re' not in i:
i['entries_re'] = [ re.compile( '^%s$' % j ) for j in i['entries'] ]
# A list of matches containing (match object, formula name, formula)
# Look for matches, ideally only one
m = [ [j.match(name),k,i] for k,i in emuFormulae.iteritems() for j in i['entries_re'] ]
m = [ j for j in m if j[0] ]
assert len(m)<=1, 'Ambiguous match (%s) for %s - giving up.'%(', '.join([j[1] for j in m]),name)
if len(m):
match = m[0][0]
formula = m[0][2]
rType = typeCode(func.ret.type)
dummyRetVal = ''
if not typeIsVoid(rType):
dummyRetVal = '(( %s )0)' % rType
emue = { 'name' : name, 'member' : member, 'ifdef' : ifdef, 'dummyretval' : dummyRetVal }
subs = deepcopy(arg)
for l in range( len(match.groups()) + 1):
subs['m%d' % l] = match.group( l )
subs['name'] = name
subs['dummyretval'] = dummyRetVal
addSubstitution( name, formula, subs )
substitute( emue, formula, 'impl', subs )
substitute( emue, formula, 'init', subs )
substitute( emue, formula, 'cond', subs )
substitute( emue, formula, 'prefix', subs )
substitute( emue, formula, 'suffix', subs )
substitute( emue, formula, 'pre', subs )
substitute( emue, formula, 'post', subs )
emue['cond'] = None
if 'cond' in formula:
emue['cond'] = formula['cond']
# plugin is optional, default to False
emue['plugin'] = False
if 'plugin' in formula:
emue['plugin'] = formula['plugin']
return emue
return None
#
# Generate code for prefix, init, cond, impl or suffix
#
def emuCodeGen(emue,section):
tmp = []
for i in emue:
if i!=None and i.get(section)!=None:
code = i[section]
if not isinstance(code,list):
code = code.strip().split('\n')
if i.get('member')!=None:
tmp.extend(wrapIf(i.get('ifdef'),wrapCIf('_context->%s'%i['member'],code)))
else:
tmp.extend(code)
return tmp