summaryrefslogtreecommitdiffstats
path: root/src/mesa/shader/program.c
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2008-10-08 14:02:24 -0600
committerBrian Paul <[email protected]>2008-10-08 14:02:24 -0600
commit5c4bd76cb65245467d4ba04e893157055d738b2d (patch)
treed3ccab98f7cdfdab3411cbebb24651117cb873a9 /src/mesa/shader/program.c
parent4f1dafaa82985bf0f04a16ba2ba2d1e8ccf83724 (diff)
mesa: in _mesa_combine_programs() take new STATE_CURRENT_ATTRIB color into account
Commit 1680ef869625dc1fe9cf481b180382a34e0738e7 changed the texenv program to get color from a state register instead of a constant-valued vertex attribute. This broke program concatenation (so glDraw/CopyPixels broke). Now check if the second program get's color from a constant register and handle that case appropriately.
Diffstat (limited to 'src/mesa/shader/program.c')
-rw-r--r--src/mesa/shader/program.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
index b03dd24d112..723c46ee8cf 100644
--- a/src/mesa/shader/program.c
+++ b/src/mesa/shader/program.c
@@ -594,17 +594,47 @@ _mesa_combine_programs(GLcontext *ctx,
if (newProg->Target == GL_FRAGMENT_PROGRAM_ARB) {
struct gl_fragment_program *fprogA, *fprogB, *newFprog;
+ GLbitfield progB_inputsRead = progB->InputsRead;
+ GLint progB_colorFile, progB_colorIndex;
+
fprogA = (struct gl_fragment_program *) progA;
fprogB = (struct gl_fragment_program *) progB;
newFprog = (struct gl_fragment_program *) newProg;
newFprog->UsesKill = fprogA->UsesKill || fprogB->UsesKill;
+ /* We'll do a search and replace for instances
+ * of progB_colorFile/progB_colorIndex below...
+ */
+ progB_colorFile = PROGRAM_INPUT;
+ progB_colorIndex = FRAG_ATTRIB_COL0;
+
+ /*
+ * The fragment program may get color from a state var rather than
+ * a fragment input (vertex output) if it's constant.
+ * See the texenvprogram.c code.
+ * So, search the program's parameter list now to see if the program
+ * gets color from a state var instead of a conventional fragment
+ * input register.
+ */
+ for (i = 0; i < progB->Parameters->NumParameters; i++) {
+ struct gl_program_parameter *p = &progB->Parameters->Parameters[i];
+ if (p->Type == PROGRAM_STATE_VAR &&
+ p->StateIndexes[0] == STATE_INTERNAL &&
+ p->StateIndexes[1] == STATE_CURRENT_ATTRIB &&
+ p->StateIndexes[2] == VERT_ATTRIB_COLOR0) {
+ progB_inputsRead |= FRAG_BIT_COL0;
+ progB_colorFile = PROGRAM_STATE_VAR;
+ progB_colorIndex = i;
+ break;
+ }
+ }
+
/* Connect color outputs of fprogA to color inputs of fprogB, via a
* new temporary register.
*/
if ((progA->OutputsWritten & (1 << FRAG_RESULT_COLR)) &&
- (progB->InputsRead & (1 << FRAG_ATTRIB_COL0))) {
+ (progB_inputsRead & FRAG_BIT_COL0)) {
GLint tempReg = _mesa_find_free_register(newProg, PROGRAM_TEMPORARY);
if (tempReg < 0) {
_mesa_problem(ctx, "No free temp regs found in "
@@ -615,13 +645,14 @@ _mesa_combine_programs(GLcontext *ctx,
replace_registers(newInst, lenA,
PROGRAM_OUTPUT, FRAG_RESULT_COLR,
PROGRAM_TEMPORARY, tempReg);
- /* replace reads from input.color[0] with tempReg */
+ /* replace reads from the input color with tempReg */
replace_registers(newInst + lenA, lenB,
- PROGRAM_INPUT, FRAG_ATTRIB_COL0,
- PROGRAM_TEMPORARY, tempReg);
+ progB_colorFile, progB_colorIndex, /* search for */
+ PROGRAM_TEMPORARY, tempReg /* replace with */ );
}
- inputsB = progB->InputsRead;
+ /* compute combined program's InputsRead */
+ inputsB = progB_inputsRead;
if (progA->OutputsWritten & (1 << FRAG_RESULT_COLR)) {
inputsB &= ~(1 << FRAG_ATTRIB_COL0);
}