/* Should be lowered by do_lower_texture_projection */
assert(!ir->projector);
- vec4_instruction *inst;
+ vec4_instruction *inst = NULL;
switch (ir->op) {
case ir_tex:
case ir_txl:
assert(!"TXB is not valid for vertex shaders.");
}
- inst->header_present = intel->gen < 5;
+ /* Texel offsets go in the message header; Gen4 also requires headers. */
+ inst->header_present = ir->offset || intel->gen < 5;
inst->base_mrf = 2;
inst->mlen = inst->header_present + 1; /* always at least one */
inst->sampler = sampler;
- inst->dst = dst_reg(this, glsl_type::get_instance(ir->type->base_type,4,1));
+ inst->dst = dst_reg(this, ir->type);
inst->shadow_compare = ir->shadow_comparitor != NULL;
+ if (ir->offset != NULL)
+ inst->texture_offset = brw_texture_offset(ir->offset->as_constant());
+
/* MRF for the first parameter */
int param_base = inst->base_mrf + inst->header_present;
emit(inst);
- this->result = src_reg(inst->dst);
+ swizzle_result(ir, src_reg(inst->dst), sampler);
+}
+
+void
+vec4_visitor::swizzle_result(ir_texture *ir, src_reg orig_val, int sampler)
+{
+ this->result = orig_val;
+
+ int s = c->key.tex.swizzles[sampler];
+
+ if (ir->op == ir_txs || ir->type == glsl_type::float_type
+ || s == SWIZZLE_NOOP)
+ return;
+
+ int zero_mask = 0, one_mask = 0, copy_mask = 0;
+ int swizzle[4];
+
+ for (int i = 0; i < 4; i++) {
+ switch (GET_SWZ(s, i)) {
+ case SWIZZLE_ZERO:
+ zero_mask |= (1 << i);
+ break;
+ case SWIZZLE_ONE:
+ one_mask |= (1 << i);
+ break;
+ default:
+ copy_mask |= (1 << i);
+ swizzle[i] = GET_SWZ(s, i);
+ break;
+ }
+ }
+
+ this->result = src_reg(this, ir->type);
+ dst_reg swizzled_result(this->result);
+
+ if (copy_mask) {
+ orig_val.swizzle = BRW_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]);
+ swizzled_result.writemask = copy_mask;
+ emit(MOV(swizzled_result, orig_val));
+ }
+
+ if (zero_mask) {
+ swizzled_result.writemask = zero_mask;
+ emit(MOV(swizzled_result, src_reg(0.0f)));
+ }
+
+ if (one_mask) {
+ swizzled_result.writemask = one_mask;
+ emit(MOV(swizzled_result, src_reg(1.0f)));
+ }
}
void