gallium/i915: fix i915_emit_texld() to handle swizzled texcoords

Allocate a temporary register, insert MOV instruction, etc.
This commit is contained in:
Brian 2008-02-25 17:59:51 -07:00
parent 2fc9d0ffac
commit 0235b32521
2 changed files with 67 additions and 16 deletions

View file

@ -71,10 +71,21 @@ i915_get_temp(struct i915_fp_compile *p)
}
p->temp_flag |= 1 << (bit - 1);
return UREG(REG_TYPE_R, (bit - 1));
return bit - 1;
}
static void
i915_release_temp(struct i915_fp_compile *p, int reg)
{
p->temp_flag &= ~(1 << reg);
}
/**
* Get unpreserved temporary, a temp whose value is not preserved between
* PS program phases.
*/
uint
i915_get_utemp(struct i915_fp_compile * p)
{
@ -183,41 +194,63 @@ i915_emit_arith(struct i915_fp_compile * p,
return dest;
}
/**
* Emit a texture load or texkill instruction.
* \param dest the dest i915 register
* \param destmask the dest register writemask
* \param sampler the i915 sampler register
* \param coord the i915 source texcoord operand
* \param opcode the instruction opcode
*/
uint i915_emit_texld( struct i915_fp_compile *p,
uint dest,
uint destmask,
uint sampler,
uint coord,
uint op )
uint opcode )
{
uint k = UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord));
const uint k = UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord));
int temp = -1;
if (coord != k) {
/* No real way to work around this in the general case - need to
* allocate and declare a new temporary register (a utemp won't
* do). Will fallback for now.
/* texcoord is swizzled or negated. Need to allocate a new temporary
* register (a utemp / unpreserved temp) won't do.
*/
i915_program_error(p, "Can't (yet) swizzle TEX arguments");
assert(0);
return 0;
uint tempReg;
temp = i915_get_temp(p); /* get temp reg index */
printf("***** ALLOC TEMP %d\n", temp);
tempReg = UREG(REG_TYPE_R, temp); /* make i915 register */
i915_emit_arith( p, A0_MOV,
tempReg, A0_DEST_CHANNEL_ALL, /* dest reg, writemask */
0, /* saturate */
coord, 0, 0 ); /* src0, src1, src2 */
/* new src texcoord is tempReg */
coord = tempReg;
}
/* Don't worry about saturate as we only support
*/
if (destmask != A0_DEST_CHANNEL_ALL) {
/* if not writing to XYZW... */
uint tmp = i915_get_utemp(p);
i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, op );
i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, opcode );
i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 );
return dest;
/* XXX release utemp here? */
}
else {
assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)));
/* is the sampler coord a texcoord input reg? */
if (GET_UREG_TYPE(coord) != REG_TYPE_T) {
p->nr_tex_indirect++;
}
*(p->csr++) = (op |
*(p->csr++) = (opcode |
T0_DEST( dest ) |
T0_SAMPLER( sampler ));
@ -225,8 +258,12 @@ uint i915_emit_texld( struct i915_fp_compile *p,
*(p->csr++) = T2_MBZ;
p->nr_tex_insn++;
return dest;
}
if (temp >= 0)
i915_release_temp(p, temp);
return dest;
}

View file

@ -575,8 +575,12 @@ i915_translate_instruction(struct i915_fp_compile *p,
src0 = src_vector(p, &inst->FullSrcRegisters[0]);
tmp = i915_get_utemp(p);
i915_emit_texld(p, tmp, A0_DEST_CHANNEL_ALL, /* use a dummy dest reg */
0, src0, T0_TEXKILL);
i915_emit_texld(p,
tmp, /* dest reg: a dummy reg */
A0_DEST_CHANNEL_ALL, /* dest writemask */
0, /* sampler */
src0, /* coord*/
T0_TEXKILL); /* opcode */
break;
case TGSI_OPCODE_LG2:
@ -970,6 +974,16 @@ i915_translate_instructions(struct i915_fp_compile *p,
ifs->num_constants = MAX2(ifs->num_constants, i + 1);
}
}
else if (parse.FullToken.FullDeclaration.Declaration.File
== TGSI_FILE_TEMPORARY) {
uint i;
for (i = parse.FullToken.FullDeclaration.u.DeclarationRange.First;
i <= parse.FullToken.FullDeclaration.u.DeclarationRange.Last;
i++) {
assert(i < I915_MAX_TEMPORARY);
p->temp_flag |= (1 << i); /* mark temp as used */
}
}
break;
case TGSI_TOKEN_TYPE_IMMEDIATE:
@ -1048,7 +1062,7 @@ i915_init_compile(struct i915_context *i915,
p->decl = p->declarations;
p->decl_s = 0;
p->decl_t = 0;
p->temp_flag = 0xffff000;
p->temp_flag = ~0x0 << I915_MAX_TEMPORARY;
p->utemp_flag = ~0x7;
p->wpos_tex = -1;