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: Mon, 27 Jan 2003 14:06:11 -0500

CVSROOT:        /cvsroot/gzz
Module name:    gzz
Changes by:     Janne V. Kujala <address@hidden>        03/01/27 14:06:11

Modified files:
        gfx/libutil    : nvcode.py 

Log message:
        Finished fp combiner emulation code but there are issues with the 
interface

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/gzz/gzz/gfx/libutil/nvcode.py.diff?tr1=1.14&tr2=1.15&r1=text&r2=text

Patches:
Index: gzz/gfx/libutil/nvcode.py
diff -u gzz/gfx/libutil/nvcode.py:1.14 gzz/gfx/libutil/nvcode.py:1.15
--- gzz/gfx/libutil/nvcode.py:1.14      Mon Jan 27 09:04:51 2003
+++ gzz/gfx/libutil/nvcode.py   Mon Jan 27 14:06:11 2003
@@ -396,21 +396,21 @@
 
 """
 REGNAME = COL0 | COL1
-        | TEX0 | TEX1 | TEX2 | TEX3
-        | SPARE0 | SPARE1
+        | TEX0 | TEX1 | TEX2 | TEX3
+        | SPARE0 | SPARE1
         | FOG
-        | CONST0 | CONST1
-        | ZERO | DISCARD 
-       | EF | SPARE0_PLUS_COL1
-
-ALPHA_COMP = a | alpha | ALPHA
-BLUE_COMP = b | blue | BLUE
-RGB_COMP = rgb | col | color | RGB | COL | COLOR
+        | CONST0 | CONST1
+        | ZERO | DISCARD 
+       | EF | SPARE0_PLUS_COL1
+
+ALPHA_COMP = a | alpha | ALPHA
+BLUE_COMP = b | blue | BLUE
+RGB_COMP = rgb | col | color | RGB | COL | COLOR
 
 REG = REGNAME
-    | REGNAME . ALPHA_COMP
-    | REGNAME . BLUE_COMP
-    | REGNAME . RGB_COMP
+    | REGNAME . ALPHA_COMP
+    | REGNAME . BLUE_COMP
+    | REGNAME . RGB_COMP
 
 IN = REG
    | (REG)
@@ -421,13 +421,13 @@
    | (1 - 2 * REG)
    | (REG - .5)
    | (.5 - REG)
-   | (0) | (.5) | (1) | (-1) | (-.5) | (-0) | (+0) | (+.5) | (+1)
+   | (0) | (.5) | (1) | (-1) | (-.5) | (-0) | (+0) | (+.5) | (+1)
 
 EXP = IN . IN 
     | IN
-    | IN * IN
+    | IN * IN
     | IN + IN
-    | IN + IN * IN
+    | IN + IN * IN
     | IN * IN + IN
     | IN * IN + IN * IN
     | IN - IN
@@ -436,28 +436,28 @@
     | IN * IN - IN 
     | -IN + IN * IN
     | IN '|' IN
-    | IN '|' IN * IN
+    | IN '|' IN * IN
     | IN * IN '|' IN
     | IN * IN '|' IN * IN
 
 BIASED_EXP = EXP
-          | EXP - .5
-          | EXP - 0
+          | EXP - .5
+          | EXP - 0
 
 OUT = BIASED_EXP
-    | (BIASED_EXP) / 2
-    | (BIASED_EXP) * .5
-    | (BIASED_EXP) * 1
-    | (BIASED_EXP) * 2
-    | (BIASED_EXP) * 4
+    | (BIASED_EXP) / 2
+    | (BIASED_EXP) * .5
+    | (BIASED_EXP) * 1
+    | (BIASED_EXP) * 2
+    | (BIASED_EXP) * 4
           
 FINAL_IN = REG
           | (1 - REG)
-          | (0) | (1)
+          | (0) | (1)
 
 FINAL_IN1 = FINAL_IN 
           | 1 - REG
-          | 0 | 1
+          | 0 | 1
 
 FINAL_OUT = FINAL_IN * FINAL_IN + FINAL_IN * FINAL_IN + FINAL_IN
           | FINAL_IN * FINAL_IN + FINAL_IN * FINAL_IN
@@ -468,10 +468,10 @@
 
 FUNC = REG '=' OUT
      | RGB_COMP '=' FINAL_OUT
-     | ALPHA_COMP '=' FINAL_IN1
+     | ALPHA_COMP '=' FINAL_IN1
      | EF '=' FINAL_IN * FINAL_IN
-     | CONST0 '=' vector
-     | CONST1 '=' vector
+     | CONST0 '=' vector
+     | CONST1 '=' vector
 """
 # Parse register combiner code from lines containing a '=' character.
 # The syntax is given by FUNC above.
@@ -602,56 +602,91 @@
 
 
 
-# Fragment program implementation of register combiners
-# Not finished yet
+# Fragment program emulation of register combiners
+# Works on raw CallGL code (i.e., on the ouput of parseCombiner).
+#
+# Usage:
+#
+#    code = <CallGL code using register combiners>
+#    foo = fpCombiner()
+#    code = foo.parseCode(code)
+#    --> combiner stuff is removed from the code except for
+#        CombinerParameter's, which are converted into ProgramEnvParameter's
+#        (program.env indicies 0, 1 and 2..17 for the per-stage constant)
+#    fp = GL.Program(foo.getFragmentProgram())
+#    --> bind and enable the returned program to emulate the combiners
+#
+# ISSUES:
+#
+# - The code is not yet tested and the interface is clumsy.
+#
+# - How should the fragment program be attached to the corresponding
+#   CallGL code? 
+#
+# - Creating a new fragment program is much more expensive than
+#   modulating some register combiner options. E.g., in libpaper,
+#   each paper would need its own emulating fragment program
+#   because, even with the same combiner type, the scaling options
+#   do change between papers.
+#
+# - Should we try to create a single fragment program that could
+#   emulate all the "combiner programs"? (Seems impossible
+#   withouth indirect register accesses)
+
 class fpCombiner:
     def __init__(self):
-        self.initializedRegs = {}
         
-        self.generalinput = [{} for i in range(0,16)]
+        self.finalInput = {}
+        self.generalInput = [{ "ALPHA" : {}, "RGB" : {} } for i in range(0,8)]
+        self.generalOutput = [{} for i in range(0,8)]
         
-        self.code = """
-        temp A, B, C, D;
-        temp AB, CD, SUM;
-        """
+        self.initmap = {
+            "TEXTURE0": "TEMP TEXTURE0; TXP TEXTURE0, fragment.texcoord[0], 
texture[0], 2D;",
+            "TEXTURE1": "TEMP TEXTURE1; TXP TEXTURE1, fragment.texcoord[1], 
texture[1], 2D;",
+            "TEXTURE2": "TEMP TEXTURE2; TXP TEXTURE2, fragment.texcoord[2], 
texture[2], 2D;",
+            "TEXTURE3": "TEMP TEXTURE3; TXP TEXTURE3, fragment.texcoord[3], 
texture[3], 2D;",
+            "PRIMARY_COLOR_NV": "TEMP PRIMARY_COLOR_NV; MOV PRIMARY_COLOR_NV, 
fragment.color.primary;",
+            "SECONDARY_COLOR_NV": "TEMP SECONDARY_COLOR_NV; MOV 
SECONDARY_COLOR_NV, fragment.color.secondary;",
+            "FOG": "TEMP FOG; MOV FOG, state.fog.color;",
+            "SPARE0_NV": "TEMP SPARE0_NV; MOV SPARE0_NV.w, TEXTURE0;",
+            "SPARE1_NV": "TEMP SPARE1_NV;",
+            "ZERO": "ALIAS ZERO = 0;",
+            "E_TIMES_F_NV": "TEMP E_TIMES_F_NV; MUL E_TIMES_F_NV, E, F;",
+            "SPARE0_PLUS_SECONDARY_COLOR_NV": "TEMP 
SPARE0_PLUS_SECONDARY_COLOR_NV; ADD SPARE0_PLUS_SECONDARY_COLOR_NV, SPARE0, 
SECONDARY_COLOR_NV;"
+            }
 
-        self.colorSumClamp = 0
-        
-        self.finalinput = {}
+        self.perStageConstants = 0
 
-    def initreg(self, reg, output = 0):
-        initmap = {
-            "TEXTURE0": "TXP TEXTURE0, fragment.texcoord[0], texture[0], 2D;",
-            "TEXTURE1": "TXP TEXTURE1, fragment.texcoord[1], texture[1], 2D;",
-            "TEXTURE2": "TXP TEXTURE2, fragment.texcoord[2], texture[2], 2D;",
-            "TEXTURE3": "TXP TEXTURE3, fragment.texcoord[3], texture[3], 2D;",
-            "PRIMARY_COLOR_NV": "mov PRIMARY_COLOR_NV, 
fragment.color.primary;",
-            "SECONDARY_COLOR_NV": "mov SECONDARY_COLOR_NV, 
fragment.color.secondary;",
-            "FOG": "mov FOG, state.fog.color;",
-            "SPARE0_NV": "mov SPARE0_NV.w, TEXTURE0;",
-            "SPARE1_NV": "",
-            "CONSTANT_COLOR0_NV": "",
-            "CONSTANT_COLOR1_NV": "",
-            "ZERO": "mov ZERO, 0;",
-            "E_TIMES_F_NV": "MUL E_TIMES_F_NV, E, F;",
-            "SPARE0_PLUS_SECONDARY_COLOR_NV": "ADD 
SPARE0_PLUS_SECONDARY_COLOR_NV, SPARE0, SECONDARY_COLOR_NV;"
-            }
 
-        if self.colorSumClamp:
-            initmap["SPARE0_PLUS_SECONDARY_COLOR_NV"] = "ADD_SAT 
SPARE0_PLUS_SECONDARY_COLOR_NV, SPARE0, SECONDARY_COLOR_NV;"
+    def initParams(self):
+        self.initializedRegs = {}
+
+        if (self.finalInput.has_key("COLOR_SUM_CLAMP_NV") and
+            self.finalInput["COLOR_SUM_CLAMP_NV"] not in ("FALSE","0")):
+            self.initmap["SPARE0_PLUS_SECONDARY_COLOR_NV"] = "ADD_SAT 
SPARE0_PLUS_SECONDARY_COLOR_NV, SPARE0, SECONDARY_COLOR_NV;"
 
-        if not self.initializedRegs.has_key(reg):
-            self.code += "TEMP %s;\n";
-            if not output:
-                if reg == "SPARE0_NV":
-                    self.initreg("TEXTURE0")
+
+    def initreg(self, reg, output = 0):
+        # Map constant colors to program.env[0..1,2..17]
+        if reg in ("CONSTANT_COLOR0_NV", "CONSTANT_COLOR1_NV"):
+            num = int(reg[14])
+            if self.perStageConstants:
+                num += 2 + 2 * self.stage
+
+            return "program.env[%s]" % num
             
-                self.code += initmap[reg] + "\n";
+        if not self.initializedRegs.has_key(reg):
+            if output:
+                self.code += "TEMP %s;\n";
+            else:
+                if reg == "SPARE0_NV": self.initreg("TEXTURE0")
+                self.code += self.initmap[reg] + "\n";
 
             self.initializedRegs[reg] = 1
-    
 
-    def genInputMapping(var, reg, mapping, comp):
+        return reg
+
+    def genInputMapping(self, var, reg, mapping, comp):
         inmap = {
             # Might need to consider clamping the SIGNED_ mappings, too.
             "UNSIGNED_IDENTITY_NV": "MOV_SAT TMP, %s;\n",
@@ -664,14 +699,14 @@
             "HALF_BIAS_NEGATE_NV":  "MOV_SAT TMP, %s; SUB TMP, .5, TMP;\n",
             }
 
-        self.initreg(reg)
+        reg = self.initreg(reg)
 
         if comp == "BLUE": reg += ".z"
         if comp == "ALPHA": reg += ".w"
 
         self.code += inmap[mapping].replace("TMP", var) % reg;
 
-    def genOutputMapping(reg, tmp, scale, bias):
+    def genOutputMapping(self, reg, tmp, scale, bias):
         self.initreg(reg, output = 1)
             
         outmap = {
@@ -691,18 +726,18 @@
         
         if abOut != "DISCARD_NV" or sumOut != "DISCARD_NV":
             if abDot:
-                self.code += "DP3 AB, A, B;\n"
+                self.code += "DP3 AB, VARIABLE_A_NV, VARIABLE_B_NV;\n"
             else:
-                self.code += "MUL AB, A, B;\n"
+                self.code += "MUL AB, VARIABLE_A_NV, VARIABLE_B_NV;\n"
                 
             if abOut != "DISCARD_NV":
                 self.genOutputMapping(abOut + suff, "AB", scale, bias);
                     
         if cdOut != "DISCARD_NV" or sumOut != "DISCARD_NV":
-            if cdDot:
-                self.code += "DP3 CD, C, D;\n"
+            if cdDot:                
+                self.code += "DP3 CD, VARIABLE_C_NV, VARIABLE_D_NV;\n"
             else:
-                self.code += "MUL CD, C, D;\n"
+                self.code += "MUL CD, VARIABLE_C_NV, VARIABLE_D_NV;\n"
 
             if cdOut != "DISCARD_NV":
                 self.genOutputMapping(cdOut + suff, "CD", scale, bias);
@@ -718,22 +753,100 @@
 
     def genFinalCombiner(self):
         self.code += """
-        # Final combiner
-        TEMP E, F, G;
+        MAD SUM, VARIABLE_A_NV, VARIABLE_B_NV, VARIABLE_D_NV;
+        TEMP invA;
+        SUB invA, 1, VARIABLE_A_NV;
+        MAD_SAT result.color.xyz, invA, VARIABLE_C_NV, SUM;
+        
+        MOV result.color.w, VARIABLE_G_NV;
         """
 
-        vars = self.finalinput
+    def parseCode(self, code):
+        out = []
+        lines = code.split("\n")
+        for line in lines:
+            fields = line.split()
+            if len(fields) == 0:
+                out.append(line)
+            # Convert constant parameters to program environment parameters:
+            elif (fields[0] == "CombinerParameterNV" and
+                fields[1] in ("CONSTANT_COLOR0_NV", "CONSTANT_COLOR1_NV")):
+                var = fields[1][14]
+                vec = fields[2:]
+                out.append("ProgramEnvParameter FRAGMENT_PROGRAM_ARB " +
+                           var + " " + " ".join(vec))
+            elif fields[0] == "CombinerStageParameterNV":
+                num = int(fields[1][8])
+                var = str(2 + 2 * num + int(fields[2][14]))
+                vec = fields[3:]
+                out.append("ProgramEnvParameter FRAGMENT_PROGRAM_ARB " +
+                           var + " " + " ".join(vec))
+            # Interpret and remove combiner specification:
+            elif fields[0] in ("FinalCombinerInputNV",
+                               "CombinerParameterNV"):
+                var = fields[1]
+                if len(fields[2:]) > 1:
+                    self.finalInput[var] = fields[2:]
+                else:
+                    self.finalInput[var] = fields[2]
+            elif fields[0] == "CombinerInputNV":
+                num = int(fields[1][8])
+                comp = fields[2]
+                var = fields[3]
+                self.generalInput[num][comp][var] = fields[4:] 
+            elif fields[0] == "CombinerOutputNV":
+                num = int(fields[1][8])
+                comp = fields[2]
+                self.generalOutput[num][comp] = fields[3:]
+            elif (fields[0] in ("Enable","Disable") and
+                     fields[1] == "PER_STAGE_CONSTANTS_NV"):
+                self.perStageConstants = fields[0] == "Enable"
+            # Pass through everything else:
+            else:
+                out.append(line)
+
+        return "\n".join(out)
+
+    def getFragmentProgram(self):
+        self.code = """!!ARBfp1.0
+        
+        TEMP VARIABLE_A_NV, VARIABLE_B_NV, VARIABLE_C_NV, VARIABLE_D_NV;
+        TEMP VARIABLE_E_NV, VARIABLE_F_NV, VARIABLE_G_NV;
+        TEMP AB, CD, SUM;
+        """
+
+        self.initParams()
+
+        combiners = int(self.finalInput["NUM_GENERAL_COMBINERS_NV"])
+        for num in range(0, combiners):
+            self.stage = num
+            for comp in "RGB", "ALPHA":
+                if self.generalOutput[num].has_key(comp):
+                    vars = self.generalInput[num][comp]
+                    for var in ("VARIABLE_A_NV",
+                                "VARIABLE_B_NV",
+                                "VARIABLE_C_NV",
+                                "VARIABLE_D_NV",):
+                        if vars.has_key(var):
+                            self.genInputMapping(var, *vars[var])
+                    self.genGeneralCombiner(*self.generalOutput[num][comp])
+
+        self.stage = -1
 
         # E and F need to be first for the proper initialization order
-        for var in "E", "F", "A", "B", "C", "D", "G":
+        vars = self.finalInput
+        for var in ("VARIABLE_E_NV",
+                    "VARIABLE_F_NV",
+                    "VARIABLE_A_NV",
+                    "VARIABLE_B_NV",
+                    "VARIABLE_C_NV",
+                    "VARIABLE_D_NV",
+                    "VARIABLE_G_NV",):
             if vars.has_key(var):
-                self.genInputMapping(var, vars[var][0], vars[var][1], 
vars[var][2])
+                self.genInputMapping(var, *vars[var])
 
-        self.code += """
-        MAD D, A, B, D;
-        TEMP invA;
-        SUB invA, 1, A;
-        MAD_SAT result.color.xyz, invA, C, D;
+        self.genFinalCombiner()
+
+        self.code += "END"
+        return self.code
         
-        MOV result.color.w, G;
-        """




reply via email to

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