mesa: add/update comments in _mesa_copy_buffer_subdata()
[mesa.git] / src / mesa / drivers / dri / i965 / brw_vec4_visitor.cpp
index b424a0f22f75262da0060471a555557ee1e9a2a8..20da487399f74e84bc439f5d77dce18f749b45d9 100644 (file)
@@ -1762,7 +1762,7 @@ vec4_visitor::visit(ir_texture *ir)
    /* 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:
@@ -1786,7 +1786,7 @@ vec4_visitor::visit(ir_texture *ir)
    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)
@@ -1878,7 +1878,56 @@ vec4_visitor::visit(ir_texture *ir)
 
    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