[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: |
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;
- """