i915: Only mark a register as available if all components are written
Previously a register would be marked as available if any component was written. This caused shaders such as this: 0: TEX TEMP[0].xyz, INPUT[14].xyyy, texture[0], 2D; 1: MUL TEMP[1], UNIFORM[0], TEMP[0].xxxx; 2: MAD TEMP[2], UNIFORM[1], TEMP[0].yyyy, TEMP[1]; 3: MAD TEMP[1], UNIFORM[2], TEMP[0].zzzz, TEMP[2]; 4: ADD TEMP[0].xyz, TEMP[1].xyzx, UNIFORM[3].xyzx; 5: TEX TEMP[1].w, INPUT[14].xyyy, texture[0], 2D; 6: MOV TEMP[0].w, TEMP[1].wwww; 7: MOV OUTPUT[2], TEMP[0]; 8: END to produce incorrect code such as this: BEGIN DCL S[0] DCL T_TEX0 R[0] = MOV T_TEX0.xyyy U[0] = TEXLD S[0],R[0] R[0].xyz = MOV U[0] R[1] = MUL CONST[0], R[0].xxxx R[2] = MAD CONST[1], R[0].yyyy, R[1] R[1] = MAD CONST[2], R[0].zzzz, R[2] R[0].xyz = ADD R[1].xyzx, CONST[3].xyzx R[0] = MOV T_TEX0.xyyy U[0] = TEXLD S[0],R[0] R[1].w = MOV U[0] R[0].w = MOV R[1].wwww oC = MOV R[0] END Note that T_TEX0 is copied to R[0], but the xyz components of R[0] are still expected to hold a calculated value. Fixes piglit tests draw-elements-vs-inputs, fp-kill, and glsl-fs-color-matrix. It also fixes Meego bugzilla #13005. NOTE: This is a candidate for the 7.9 and 7.10 branches.
This commit is contained in:
parent
20d278a7ff
commit
a04582739e
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue