Merge remote branch 'origin/master' into lp-setup-llvm
[mesa.git] / src / mesa / drivers / dri / i965 / brw_fs.cpp
index e372f3a13da2f0eb1f59b5ff53790f4bc3b094f4..554ba39a0cd9b12086c846d829f61334061b8458 100644 (file)
@@ -91,58 +91,56 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
 {
    struct intel_context *intel = intel_context(ctx);
 
-   for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
-      struct brw_shader *shader = (struct brw_shader *)prog->_LinkedShaders[i];
-
-      if (shader->base.Type == GL_FRAGMENT_SHADER) {
-        void *mem_ctx = talloc_new(NULL);
-        bool progress;
-
-        if (shader->ir)
-           talloc_free(shader->ir);
-        shader->ir = new(shader) exec_list;
-        clone_ir_list(mem_ctx, shader->ir, shader->base.ir);
-
-        do_mat_op_to_vec(shader->ir);
-        do_mod_to_fract(shader->ir);
-        do_div_to_mul_rcp(shader->ir);
-        do_sub_to_add_neg(shader->ir);
-        do_explog_to_explog2(shader->ir);
-        do_lower_texture_projection(shader->ir);
-        brw_do_cubemap_normalize(shader->ir);
-
-        do {
-           progress = false;
-
-           brw_do_channel_expressions(shader->ir);
-           brw_do_vector_splitting(shader->ir);
-
-           progress = do_lower_jumps(shader->ir, true, true,
-                                     true, /* main return */
-                                     false, /* continue */
-                                     false /* loops */
-                                     ) || progress;
-
-           progress = do_common_optimization(shader->ir, true, 32) || progress;
-
-           progress = lower_noise(shader->ir) || progress;
-           progress =
-              lower_variable_index_to_cond_assign(shader->ir,
-                                                  GL_TRUE, /* input */
-                                                  GL_TRUE, /* output */
-                                                  GL_TRUE, /* temp */
-                                                  GL_TRUE /* uniform */
-                                                  ) || progress;
-           if (intel->gen == 6) {
-              progress = do_if_to_cond_assign(shader->ir) || progress;
-           }
-        } while (progress);
+   struct brw_shader *shader =
+      (struct brw_shader *)prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
+   if (shader != NULL) {
+      void *mem_ctx = talloc_new(NULL);
+      bool progress;
 
-        validate_ir_tree(shader->ir);
+      if (shader->ir)
+        talloc_free(shader->ir);
+      shader->ir = new(shader) exec_list;
+      clone_ir_list(mem_ctx, shader->ir, shader->base.ir);
 
-        reparent_ir(shader->ir, shader->ir);
-        talloc_free(mem_ctx);
-      }
+      do_mat_op_to_vec(shader->ir);
+      do_mod_to_fract(shader->ir);
+      do_div_to_mul_rcp(shader->ir);
+      do_sub_to_add_neg(shader->ir);
+      do_explog_to_explog2(shader->ir);
+      do_lower_texture_projection(shader->ir);
+      brw_do_cubemap_normalize(shader->ir);
+
+      do {
+        progress = false;
+
+        brw_do_channel_expressions(shader->ir);
+        brw_do_vector_splitting(shader->ir);
+
+        progress = do_lower_jumps(shader->ir, true, true,
+                                  true, /* main return */
+                                  false, /* continue */
+                                  false /* loops */
+                                  ) || progress;
+
+        progress = do_common_optimization(shader->ir, true, 32) || progress;
+
+        progress = lower_noise(shader->ir) || progress;
+        progress =
+           lower_variable_index_to_cond_assign(shader->ir,
+                                               GL_TRUE, /* input */
+                                               GL_TRUE, /* output */
+                                               GL_TRUE, /* temp */
+                                               GL_TRUE /* uniform */
+                                               ) || progress;
+        if (intel->gen == 6) {
+           progress = do_if_to_cond_assign(shader->ir) || progress;
+        }
+      } while (progress);
+
+      validate_ir_tree(shader->ir);
+
+      reparent_ir(shader->ir, shader->ir);
+      talloc_free(mem_ctx);
    }
 
    if (!_mesa_ir_link_shader(ctx, prog))
@@ -182,7 +180,8 @@ type_size(const struct glsl_type *type)
 }
 
 static const fs_reg reg_undef;
-static const fs_reg reg_null(ARF, BRW_ARF_NULL);
+static const fs_reg reg_null_f(ARF, BRW_ARF_NULL, BRW_REGISTER_TYPE_F);
+static const fs_reg reg_null_d(ARF, BRW_ARF_NULL, BRW_REGISTER_TYPE_D);
 
 int
 fs_visitor::virtual_grf_alloc(int size)
@@ -211,6 +210,15 @@ fs_reg::fs_reg(enum register_file file, int hw_reg)
    this->type = BRW_REGISTER_TYPE_F;
 }
 
+/** Fixed HW reg constructor. */
+fs_reg::fs_reg(enum register_file file, int hw_reg, uint32_t type)
+{
+   init();
+   this->file = file;
+   this->hw_reg = hw_reg;
+   this->type = type;
+}
+
 int
 brw_type_for_base_type(const struct glsl_type *type)
 {
@@ -574,7 +582,7 @@ fs_visitor::emit_math(fs_opcodes opcode, fs_reg dst, fs_reg src0, fs_reg src1)
       inst = emit(fs_inst(opcode, dst, src0, src1));
    } else {
       emit(fs_inst(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + 1), src1));
-      inst = emit(fs_inst(opcode, dst, src0, reg_null));
+      inst = emit(fs_inst(opcode, dst, src0, reg_null_f));
 
       inst->base_mrf = base_mrf;
       inst->mlen = 2;
@@ -727,12 +735,12 @@ fs_visitor::visit(ir_expression *ir)
 
       emit(fs_inst(BRW_OPCODE_MOV, this->result, fs_reg(0.0f)));
 
-      inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], fs_reg(0.0f)));
+      inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_f, op[0], fs_reg(0.0f)));
       inst->conditional_mod = BRW_CONDITIONAL_G;
       inst = emit(fs_inst(BRW_OPCODE_MOV, this->result, fs_reg(1.0f)));
       inst->predicated = true;
 
-      inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], fs_reg(0.0f)));
+      inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_f, op[0], fs_reg(0.0f)));
       inst->conditional_mod = BRW_CONDITIONAL_L;
       inst = emit(fs_inst(BRW_OPCODE_MOV, this->result, fs_reg(-1.0f)));
       inst->predicated = true;
@@ -1043,7 +1051,7 @@ fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate)
        */
       assert(ir->op == ir_txb || ir->op == ir_txl);
 
-      for (int i = 0; i < ir->coordinate->type->vector_elements * 2;) {
+      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
         emit(fs_inst(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i * 2),
                      coordinate));
         coordinate.reg_offset++;
@@ -1305,8 +1313,8 @@ fs_visitor::visit(ir_discard *ir)
 
    assert(ir->condition == NULL); /* FINISHME */
 
-   emit(fs_inst(FS_OPCODE_DISCARD_NOT, temp, reg_null));
-   emit(fs_inst(FS_OPCODE_DISCARD_AND, reg_null, temp));
+   emit(fs_inst(FS_OPCODE_DISCARD_NOT, temp, reg_null_d));
+   emit(fs_inst(FS_OPCODE_DISCARD_AND, reg_null_d, temp));
    kill_emitted = true;
 }
 
@@ -1355,67 +1363,68 @@ fs_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
 
       switch (expr->operation) {
       case ir_unop_logic_not:
-        inst = emit(fs_inst(BRW_OPCODE_ADD, reg_null, op[0], fs_reg(-1)));
-        inst->conditional_mod = BRW_CONDITIONAL_NZ;
+        inst = emit(fs_inst(BRW_OPCODE_AND, reg_null_d, op[0], fs_reg(1)));
+        inst->conditional_mod = BRW_CONDITIONAL_Z;
         break;
 
       case ir_binop_logic_xor:
-        inst = emit(fs_inst(BRW_OPCODE_XOR, reg_null, op[0], op[1]));
+        inst = emit(fs_inst(BRW_OPCODE_XOR, reg_null_d, op[0], op[1]));
         inst->conditional_mod = BRW_CONDITIONAL_NZ;
         break;
 
       case ir_binop_logic_or:
-        inst = emit(fs_inst(BRW_OPCODE_OR, reg_null, op[0], op[1]));
+        inst = emit(fs_inst(BRW_OPCODE_OR, reg_null_d, op[0], op[1]));
         inst->conditional_mod = BRW_CONDITIONAL_NZ;
         break;
 
       case ir_binop_logic_and:
-        inst = emit(fs_inst(BRW_OPCODE_AND, reg_null, op[0], op[1]));
+        inst = emit(fs_inst(BRW_OPCODE_AND, reg_null_d, op[0], op[1]));
         inst->conditional_mod = BRW_CONDITIONAL_NZ;
         break;
 
       case ir_unop_f2b:
         if (intel->gen >= 6) {
-           inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], fs_reg(0.0f)));
+           inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_d,
+                               op[0], fs_reg(0.0f)));
         } else {
-           inst = emit(fs_inst(BRW_OPCODE_MOV, reg_null, op[0]));
+           inst = emit(fs_inst(BRW_OPCODE_MOV, reg_null_d, op[0]));
         }
         inst->conditional_mod = BRW_CONDITIONAL_NZ;
         break;
 
       case ir_unop_i2b:
         if (intel->gen >= 6) {
-           inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], fs_reg(0)));
+           inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_d, op[0], fs_reg(0)));
         } else {
-           inst = emit(fs_inst(BRW_OPCODE_MOV, reg_null, op[0]));
+           inst = emit(fs_inst(BRW_OPCODE_MOV, reg_null_d, op[0]));
         }
         inst->conditional_mod = BRW_CONDITIONAL_NZ;
         break;
 
       case ir_binop_greater:
-        inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], op[1]));
+        inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_d, op[0], op[1]));
         inst->conditional_mod = BRW_CONDITIONAL_G;
         break;
       case ir_binop_gequal:
-        inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], op[1]));
+        inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_d, op[0], op[1]));
         inst->conditional_mod = BRW_CONDITIONAL_GE;
         break;
       case ir_binop_less:
-        inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], op[1]));
+        inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_d, op[0], op[1]));
         inst->conditional_mod = BRW_CONDITIONAL_L;
         break;
       case ir_binop_lequal:
-        inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], op[1]));
+        inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_d, op[0], op[1]));
         inst->conditional_mod = BRW_CONDITIONAL_LE;
         break;
       case ir_binop_equal:
       case ir_binop_all_equal:
-        inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], op[1]));
+        inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_d, op[0], op[1]));
         inst->conditional_mod = BRW_CONDITIONAL_Z;
         break;
       case ir_binop_nequal:
       case ir_binop_any_nequal:
-        inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], op[1]));
+        inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_d, op[0], op[1]));
         inst->conditional_mod = BRW_CONDITIONAL_NZ;
         break;
       default:
@@ -1429,11 +1438,11 @@ fs_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
    ir->accept(this);
 
    if (intel->gen >= 6) {
-      fs_inst *inst = emit(fs_inst(BRW_OPCODE_AND, reg_null,
+      fs_inst *inst = emit(fs_inst(BRW_OPCODE_AND, reg_null_d,
                                   this->result, fs_reg(1)));
       inst->conditional_mod = BRW_CONDITIONAL_NZ;
    } else {
-      fs_inst *inst = emit(fs_inst(BRW_OPCODE_MOV, reg_null, this->result));
+      fs_inst *inst = emit(fs_inst(BRW_OPCODE_MOV, reg_null_d, this->result));
       inst->conditional_mod = BRW_CONDITIONAL_NZ;
    }
 }
@@ -1498,7 +1507,7 @@ fs_visitor::visit(ir_loop *ir)
       this->base_ir = ir->to;
       ir->to->accept(this);
 
-      fs_inst *inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null,
+      fs_inst *inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_d,
                                   counter, this->result));
       switch (ir->cmp) {
       case ir_binop_equal:
@@ -1993,17 +2002,17 @@ fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst)
          */
         msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE;
         if (inst->shadow_compare) {
-           assert(inst->mlen == 5);
+           assert(inst->mlen == 6);
         } else {
-           assert(inst->mlen <= 6);
+           assert(inst->mlen <= 4);
         }
         break;
       case FS_OPCODE_TXB:
         if (inst->shadow_compare) {
-           assert(inst->mlen == 5);
+           assert(inst->mlen == 6);
            msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE;
         } else {
-           assert(inst->mlen == 8);
+           assert(inst->mlen == 9);
            msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS;
            simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD16;
         }
@@ -3182,18 +3191,13 @@ brw_wm_fs_emit(struct brw_context *brw, struct brw_wm_compile *c)
    struct brw_compile *p = &c->func;
    struct intel_context *intel = &brw->intel;
    struct gl_context *ctx = &intel->ctx;
-   struct brw_shader *shader = NULL;
    struct gl_shader_program *prog = ctx->Shader.CurrentProgram;
 
    if (!prog)
       return GL_FALSE;
 
-   for (unsigned int i = 0; i < prog->_NumLinkedShaders; i++) {
-      if (prog->_LinkedShaders[i]->Type == GL_FRAGMENT_SHADER) {
-        shader = (struct brw_shader *)prog->_LinkedShaders[i];
-        break;
-      }
-   }
+   struct brw_shader *shader =
+     (brw_shader *) prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
    if (!shader)
       return GL_FALSE;
 
@@ -3284,6 +3288,11 @@ brw_wm_fs_emit(struct brw_context *brw, struct brw_wm_compile *c)
               printf("   %s\n", last_annotation_string);
         }
         brw_disasm(stdout, &p->store[i], intel->gen);
+        printf("0x%08x 0x%08x 0x%08x 0x%08x\n",
+               ((uint32_t *)&p->store[i])[3],
+               ((uint32_t *)&p->store[i])[2],
+               ((uint32_t *)&p->store[i])[1],
+               ((uint32_t *)&p->store[i])[0]);
       }
       printf("\n");
    }