mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-03 09:58:05 +02:00
gallium/i915: fix i915_emit_texld() to handle swizzled texcoords
Allocate a temporary register, insert MOV instruction, etc.
This commit is contained in:
parent
2fc9d0ffac
commit
0235b32521
2 changed files with 67 additions and 16 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue