[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gzz-commits] gzz/gfx/libutil nvcode.py
From: |
Janne V. Kujala |
Subject: |
[Gzz-commits] gzz/gfx/libutil nvcode.py |
Date: |
Fri, 22 Nov 2002 03:41:27 -0500 |
CVSROOT: /cvsroot/gzz
Module name: gzz
Changes by: Janne V. Kujala <address@hidden> 02/11/22 03:41:27
Modified files:
gfx/libutil : nvcode.py
Log message:
Start simple combiner code parser
CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/gzz/gzz/gfx/libutil/nvcode.py.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
Patches:
Index: gzz/gfx/libutil/nvcode.py
diff -u gzz/gfx/libutil/nvcode.py:1.3 gzz/gfx/libutil/nvcode.py:1.4
--- gzz/gfx/libutil/nvcode.py:1.3 Tue Oct 29 11:34:04 2002
+++ gzz/gfx/libutil/nvcode.py Fri Nov 22 03:41:27 2002
@@ -34,3 +34,403 @@
elif x < 1.5: return "NONE"
elif x < 3: return "SCALE_BY_TWO_NV"
return "SCALE_BY_FOUR_NV"
+
+
+def matchop(str,i):
+ def opchar(str, i):
+ return i < len(str) and str[i] in [ "*", "/", "+", "-", ".", "|" ]
+ if opchar(str, i): return i + 1
+ return 0
+
+def matchid(str, i):
+ def idchar(str, i):
+ return i < len(str) and ("0" <= str[i] <= "9" or
+ "A" <= str[i] <= "Z" or
+ "a" <= str[i] <= "z" or
+ str[i] == "_")
+ if not idchar(str, i): return 0
+ while idchar(str, i): i += 1
+ return i
+
+def matchnum(str, i):
+ if (i < len(str) and "0" <= str[i] <= "9") or (
+ i + 1 < len(str) and str[i] == "." and "0" <= str[i + 1] <= "9"):
+ while i < len(str) and (str[i] == "." or "0" <= str[i] <= "9"): i += 1
+ return i
+ return 0
+
+def exptree(exp, i):
+ if i == len(exp): return ([], i)
+
+ if exp[i] in [" ", "\t"]:
+ return exptree(exp, i + 1)
+ elif exp[i] == "(":
+ (subtree, pos) = exptree(exp, i + 1)
+ car = ("sub", subtree)
+ if pos == len(exp):
+ print "WARNING: Missing closing parenthesis"
+ else:
+ pos += 1
+ elif exp[i] == ")":
+ return ([], i)
+ else:
+ pos = matchnum(exp, i)
+ if pos:
+ car = (float(exp[i:pos]),)
+ else:
+ pos = matchid(exp, i)
+ if pos:
+ car = ("id", exp[i:pos])
+ else:
+ pos = matchop(exp, i)
+
+ if pos:
+ car = (exp[i:pos],)
+ else:
+ return ([], i)
+
+ (cdr,i) = exptree(exp, pos)
+
+ return ([car] + cdr,i)
+
+
+def printtree(tree, pre = ""):
+ for node in tree:
+ if node[0] == "sub":
+ printtree(node[1], pre + "> ")
+ else:
+ if len(node) == 1: node = node[0]
+ print pre + str(node)
+
+def parsecomp(name):
+ if name in ["a", "alpha"]: return "ALPHA"
+ if name in ["b", "blue"]: return "BLUE"
+ if name in ["rgb", "color", "col"]: return "RGB"
+ return None
+
+def parseregs(tree):
+ regmap = {
+ "COL0": "PRIMARY_COLOR_NV",
+ "COL1": "SECONDARY_COLOR_NV",
+ "TEX0": "TEXTURE0",
+ "TEX1": "TEXTURE1",
+ "TEX2": "TEXTURE2",
+ "TEX3": "TEXTURE3",
+ "SPARE0": "SPARE0_NV",
+ "SPARE1": "SPARE1_NV",
+ "FOG": "FOG",
+ "CONST0": "CONSTANT_COLOR0_NV",
+ "CONST1": "CONSTANT_COLOR1_NV",
+ "ZERO": "ZERO",
+ "EF": "E_TIMES_F_NV",
+ "SPARE0_PLUS_COL1" : "SPARE0_PLUS_SECONDARY_COLOR_NV",
+ }
+
+ i = 0
+ while i < len(tree):
+ node = tree[i]
+ if node[0] == "sub":
+ parseregs(node[1])
+ else:
+ if node[0] == "id" and regmap.has_key(node[1]):
+ if (i + 2 < len(tree) and
+ tree[i+1] == (".",) and
+ tree[i+2][0] == "id" and
+ parsecomp(tree[i+2][1])):
+ tree[i:i+3] = [("reg", regmap[node[1]],
+ parsecomp(tree[i+2][1]))]
+ else:
+ tree[i:i+1] = [("reg", regmap[node[1]], "RGB")]
+ i += 1
+
+def findregs(list, type = "reg"):
+ indlist = []
+ for i in range(0,len(list)):
+ if list[i] == type: indlist.append(i)
+ return indlist
+
+def parseinput(tree):
+ inputmap = {
+ ("+", "reg"): "SIGNED_IDENTITY_NV",
+ ("reg",): "UNSIGNED_IDENTITY_NV",
+ (2, "reg", "-", 1): "EXPAND_NORMAL_NV",
+ (2, "*", "reg", "-", 1): "EXPAND_NORMAL_NV",
+ ("reg", "-", .5): "HALF_BIAS_NORMAL_NV",
+ ("-", "reg"): "SIGNED_NEGATE_NV",
+ (1, "-", "reg"): "UNSIGNED_INVERT_NV",
+ (1, "-", 2, "reg"): "EXPAND_NEGATE_NV",
+ (1, "-", 2, "*", "reg"): "EXPAND_NEGATE_NV",
+ (.5, "-", "reg"): "HALF_BIAS_NEGATE"
+ }
+
+ key = tuple(map(lambda node: node[0], tree))
+
+ if inputmap.has_key(key):
+ i = findregs(key)[0]
+ tree[:] = [("in", tree[i][1], inputmap[key], tree[i][2])]
+ else:
+ for i in range(0,len(tree)):
+ if tree[i][0] == "sub":
+ parseinput(tree[i][1])
+ if len(tree[i][1]) == 1:
+ tree[i] = tree[i][1][0]
+ elif tree[i][0] == "reg":
+ tree[i] = ("in", tree[i][1], inputmap["reg",], tree[i][2])
+
+def setcheck(hash, name, value):
+ if hash.has_key(name):
+ if hash[name] != value:
+ print "ERROR: Incompatible <" + name + ">'s"
+ return 0
+ else:
+ hash[name] = value
+ return 1
+
+def parseoutput(tree, out, outreg = "OUTREG"):
+
+ scale = "NONE"
+ bias = "NONE"
+
+ outputscale = {
+ ("*", .5): "SCALE_BY_ONE_HALF_NV",
+ ("/", 2): "SCALE_BY_ONE_HALF_NV",
+ ("*", 1): "NONE",
+ ("*", 2): "SCALE_BY_TWO_NV",
+ ("*", 4): "SCALE_BY_FOUR_NV"
+ }
+ outputbias = {
+ ("-", .5): "BIAS_BY_NEGATIVE_ONE_HALF_NV",
+ }
+
+ l = map(lambda node: node[0], tree)
+ if len(l) >= 2:
+ key = tuple(l[1:])
+ if outputscale.has_key(key):
+ scale = outputscale[key]
+ tree[:] = tree[:-2]
+ if len(tree) == 1 and tree[0][0] == "sub":
+ tree[:] = tree[0][1]
+
+ l = map(lambda node: node[0], tree)
+ if len(l) >= 2:
+ key = tuple(l[-2:])
+ if outputbias.has_key(key):
+ bias = outputbias[key]
+ tree[:] = tree[:-2]
+
+ setcheck(out, "bias", bias)
+ setcheck(out, "scale", scale)
+
+ funcmap1 = {
+ ("in", ".", "in"): ("AB", "TRUE"),
+ ("in",): ("A", "FALSE"),
+ ("in", "*", "in"): ("AB", "TRUE"),
+ }
+
+ funcmap2 = {
+ ("in", "+", "in"): ("AC", "FALSE"),
+ ("in", "+", "in", "*", "in"): ("ACD", "FALSE"),
+ ("in", "*", "in", "+", "in"): ("ABC", "FALSE"),
+ ("in", "*", "in", "+", "in", "*", "in"): ("ABCD", "FALSE"),
+ ("in", "|", "in"): ("AC", "TRUE"),
+ ("in", "|", "in", "*", "in"): ("ACD", "TRUE"),
+ ("in", "*", "in", "|", "in"): ("ABC", "TRUE"),
+ ("in", "*", "in", "|", "in", "*", "in"): ("ABCD", "TRUE"),
+ }
+
+ key = tuple(map(lambda node: node[0], tree))
+ if funcmap1.has_key(key):
+ func = funcmap1[key]
+ regs = findregs(key, "in")
+
+ foo = [ " ".join(tree[reg][1:]) for reg in regs ]
+ if len(foo) == 1: foo += ["ZERO UNSIGNED_IDENTITY_NV ALPHA"]
+
+ if (out.has_key("A") and out["A"] != foo[0] or
+ out.has_key("B") and out["B"] != foo[1] or
+ out.has_key("abDot") and out["abDot"] != func[1] or
+ out.has_key("abOut")):
+ setcheck(out, "C", foo[0])
+ setcheck(out, "D", foo[1])
+ setcheck(out, "cdDot", func[1])
+ setcheck(out, "cdOut", outreg)
+ else:
+ setcheck(out, "A", foo[0])
+ setcheck(out, "B", foo[1])
+ setcheck(out, "abDot", func[1])
+ setcheck(out, "abOut", outreg)
+
+ elif funcmap2.has_key(key):
+ func = funcmap2[key]
+ regs = findregs(key, "in")
+
+ for i in range(0,len(regs)):
+ setcheck(out, func[0][i], " ".join(tree[regs[i]][1:]))
+
+ for name in "ABCD":
+ if name not in func[0]:
+ setcheck(out, name, "ZERO UNSIGNED_IDENTITY_NV ALPHA")
+
+ setcheck(out, "sumOut", outreg)
+ setcheck(out, "muxSum", func[1])
+ else:
+ print "Function not recognized"
+ printtree(tree)
+ return 0
+
+ return 1
+
+# Parse general combiner stage code from lines such as
+# SPARE0 = (COL0 . COL1 - .5) * 2
+# SPARE1 = (CONST0 * (1 - COL0) - .5) * 2
+# SPARE0.alpha = (1 - 2 * COL0.alpha) + COL1.blue
+def parseGeneralCombiner(lines, stage = 0):
+ out = {
+ "RGB": {},
+ "ALPHA": {}
+ }
+
+ for line in lines:
+ mid = line.find("=")
+ if mid == -1:
+ print "ERROR: '=' not found:", line
+ return ""
+
+ (left, lend) = exptree(line, 0)
+ (right, rend) = exptree(line, mid + 1)
+ if lend < mid:
+ print "ERROR: extra input:", line[lend:mid]
+ return ""
+ if rend < len(line):
+ print "ERROR: extra input:", line[rend:]
+ return ""
+
+ parseregs(left)
+ parseregs(right)
+
+ if len(left) != 1 or left[0][0] != "reg":
+ print "ERROR: left side not a register:"
+ printtree(left)
+ return ""
+
+ outreg = left[0][1]
+ outcomp = left[0][2]
+
+ parseinput(right)
+ if not parseoutput(right, out[outcomp], outreg):
+ return ""
+
+ code = "".join(map(lambda x: "# " + x + "\n", lines))
+ for comp in "RGB", "ALPHA":
+ if out[comp]:
+ for var in "A", "B", "C", "D":
+ if out[comp].has_key(var):
+ code += (
+ "CombinerInputNV COMBINER%s_NV %s VARIABLE_%s_NV %s\n"
+ % (stage, comp, var, out[comp][var]))
+
+ code += (
+ "CombinerOutputNV COMBINER%s_NV %s %s %s %s %s %s %s %s %s\n"
+ % (stage, comp,
+ out[comp].get("abOut", "DISCARD_NV"),
+ out[comp].get("cdOut", "DISCARD_NV"),
+ out[comp].get("sumOut", "DISCARD_NV"),
+ out[comp]["scale"],
+ out[comp]["bias"],
+ out[comp].get("abDot", "FALSE"),
+ out[comp].get("cdDot", "FALSE"),
+ out[comp].get("muxSum", "FALSE"),
+ )
+ )
+
+ return code
+
+
+# Parse final combiner code from lines such as
+# alpha = 1-SPARE0
+# EF = COL0 * (1 - COL1.alpha)
+# color = EF * FOG + (1-EF) * SPARE1
+def parseFinalCombiner(lines):
+ code = "".join(map(lambda x: "# " + x + "\n", lines))
+ for line in lines:
+ mid = line.find("=")
+ if mid == -1:
+ print "ERROR: '=' not found:", line
+ return ""
+
+ (left, lend) = exptree(line, 0)
+ (right, rend) = exptree(line, mid + 1)
+ if lend < mid:
+ print "ERROR: extra input:", line[lend:mid]
+ return ""
+ if rend < len(line):
+ print "ERROR: extra input:", line[rend:]
+ return ""
+
+ outreg = None
+ if len(left) == 1 and left[0][0] == "id":
+ if left[0][1] == "EF":
+ outreg = "EF"
+ else:
+ outreg = parsecomp(left[0][1])
+
+ if outreg not in ["EF", "RGB", "ALPHA"]:
+ print "ERROR: left side must be EF, color, or alpha:"
+ printtree(left)
+ return ""
+
+ parseregs(right)
+ parseinput(right)
+
+ key = tuple(map(lambda node: node[0], right))
+
+ if outreg == "EF":
+ if key != ("in", "*", "in"):
+ print "ERROR: EF must be a product"
+ printtree(right)
+ return ""
+ code += ("FinalCombinerInput VARIABLE_E_NV " +
+ " ".join(right[0][1:]) + "\n" +
+ "FinalCombinerInput VARIABLE_F_NV " +
+ " ".join(right[2][1:]) + "\n")
+ elif outreg == "ALPHA":
+ if key != ("in",):
+ print "ERROR: alpha must be an input mapped register"
+ printtree(right)
+ return ""
+ code += ("FinalCombinerInput VARIABLE_G_NV " +
+ " ".join(right[0][1:]) + "\n")
+ else:
+ funcmap = {
+ ("in", "*", "in", "+", "in", "*", "in", "+", "in"): "ABACD",
+ ("in", "*", "in", "+", "in", "*", "in"): "ABAC",
+ ("in", "*", "in"): "AB",
+ ("in"): "D",
+ }
+ if funcmap.has_key(key):
+ func = funcmap[key]
+ regs = findregs(key, "in")
+
+ for i in range(0,len(regs)):
+ inreg = [foo for foo in right[regs[i]][1:]]
+
+ if i > 0 and func[i] == "A":
+ if inreg[1] == "UNSIGNED_IDENTITY_NV":
+ inreg[1] = "UNSIGNED_INVERT_NV"
+ if inreg[1] == "UNSIGNED_INVERT_NV":
+ inreg[1] = "UNSIGNED_IDENTITY_NV"
+ if inreg[1] != right[0][2] or inreg[0] != right[0][1]:
+ print "ERROR: inconsistent A variables"
+ printtree(right)
+ return ""
+ else:
+ code += ("FinalCombinerInput VARIABLE_%s_NV %s\n"
+ % (func[i], " ".join(inreg)))
+
+ for reg in "ABCD":
+ if reg not in func:
+ code += ("FinalCombinerInput VARIABLE_%s_NV "
+ "ZERO UNSIGNED_IDENTITY_NV ALPHA\n" % reg)
+
+ return code
+
- [Gzz-commits] gzz/gfx/libutil nvcode.py,
Janne V. Kujala <=