summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/i915/i915_fragprog.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c
index 1c6e984517..624f18d671 100644
--- a/src/mesa/drivers/dri/i915/i915_fragprog.c
+++ b/src/mesa/drivers/dri/i915/i915_fragprog.c
@@ -306,6 +306,7 @@ static void calc_live_regs( struct i915_fragment_program *p )
{
const struct gl_fragment_program *program = p->ctx->FragmentProgram._Current;
GLuint regsUsed = 0xffff0000;
+ uint8_t live_components[16] = { 0, };
GLint i;
for (i = program->Base.NumInstructions - 1; i >= 0; i--) {
@@ -314,13 +315,26 @@ static void calc_live_regs( struct i915_fragment_program *p )
int a;
/* Register is written to: unmark as live for this and preceeding ops */
- if (inst->DstReg.File == PROGRAM_TEMPORARY)
- regsUsed &= ~(1 << inst->DstReg.Index);
+ if (inst->DstReg.File == PROGRAM_TEMPORARY) {
+ live_components[inst->DstReg.Index] &= ~inst->DstReg.WriteMask;
+ if (live_components[inst->DstReg.Index] == 0)
+ regsUsed &= ~(1 << inst->DstReg.Index);
+ }
for (a = 0; a < opArgs; a++) {
/* Register is read from: mark as live for this and preceeding ops */
- if (inst->SrcReg[a].File == PROGRAM_TEMPORARY)
+ if (inst->SrcReg[a].File == PROGRAM_TEMPORARY) {
+ unsigned c;
+
regsUsed |= 1 << inst->SrcReg[a].Index;
+
+ for (c = 0; c < 4; c++) {
+ const unsigned field = GET_SWZ(inst->SrcReg[a].Swizzle, c);
+
+ if (field <= SWIZZLE_W)
+ live_components[inst->SrcReg[a].Index] |= (1U << field);
+ }
+ }
}
p->usedRegs[i] = regsUsed;