* \param opcode the instruction opcode
*/
uint i915_emit_texld( struct i915_fp_compile *p,
- uint dest,
- uint destmask,
- uint sampler,
- uint coord,
- uint opcode )
+ uint dest,
+ uint destmask,
+ uint sampler,
+ uint coord,
+ uint opcode,
+ uint num_coord )
{
const uint k = UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord));
+
int temp = -1;
+ uint ignore = 0;
+
+ /* Eliminate the useless texture coordinates. Otherwise we end up generating
+ * a swizzle for no reason below. */
+ switch(num_coord) {
+ case 0:
+ /* Ignore x */
+ ignore |= (0xf << UREG_CHANNEL_X_SHIFT);
+ case 1:
+ /* Ignore y */
+ ignore |= (0xf << UREG_CHANNEL_Y_SHIFT);
+ case 2:
+ /* Ignore z */
+ ignore |= (0xf << UREG_CHANNEL_Z_SHIFT);
+ case 3:
+ /* Ignore w */
+ ignore |= (0xf << UREG_CHANNEL_W_SHIFT);
+ }
- if (coord != k) {
+ if ( (coord &~ignore ) != (k & ~ignore) ) {
/* texcoord is swizzled or negated. Need to allocate a new temporary
* register (a utemp / unpreserved temp) won't do.
*/
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, opcode );
+ i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, opcode, num_coord );
i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 );
/* XXX release utemp here? */
}
}
}
+/**
+ * Convert TGSI_TEXTURE_x token to DO_SAMPLE_TYPE_x token
+ */
+static uint
+texture_num_coords(struct i915_fp_compile *p, uint tex)
+{
+ switch (tex) {
+ case TGSI_TEXTURE_SHADOW1D:
+ case TGSI_TEXTURE_1D:
+ return 1;
+
+ case TGSI_TEXTURE_SHADOW2D:
+ case TGSI_TEXTURE_2D:
+ case TGSI_TEXTURE_SHADOWRECT:
+ case TGSI_TEXTURE_RECT:
+ return 2;
+
+ case TGSI_TEXTURE_3D:
+ case TGSI_TEXTURE_CUBE:
+ return 3;
+
+ default:
+ i915_program_error(p, "Num coords");
+ return 2;
+ }
+}
+
/**
* Generate texel lookup instruction.
get_result_flags( inst ),
sampler,
coord,
- opcode);
+ opcode,
+ texture_num_coords(p, texture) );
}
A0_DEST_CHANNEL_ALL, /* dest writemask */
0, /* sampler */
src0, /* coord*/
- T0_TEXKILL); /* opcode */
+ T0_TEXKILL, /* opcode */
+ 1); /* num_coord */
break;
case TGSI_OPCODE_KILP: