gzz-commits
[Top][All Lists]
Advanced

[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
+    




reply via email to

[Prev in Thread] Current Thread [Next in Thread]