radeon: make texture logging more useful
[mesa.git] / src / gallium / drivers / r600 / sb / sb_shader.cpp
index 91f7c5dba5eb7b5b732beda3b66d5ea52693952d..98e52b16e0e3beac7d5137739315cbf610faf5b6 100644 (file)
 
 #include "sb_bc.h"
 #include "sb_shader.h"
-
 #include "sb_pass.h"
 
 namespace r600_sb {
 
-using std::cerr;
-
-shader::shader(sb_context &sctx, shader_target t, unsigned id, bool dump)
+shader::shader(sb_context &sctx, shader_target t, unsigned id)
 : ctx(sctx), next_temp_value_index(temp_regid_offset),
   prep_regs_count(), pred_sels(),
   regions(), inputs(), undef(), val_pool(sizeof(value)),
-  pool(), all_nodes(), errors(), enable_dump(dump),
+  pool(), all_nodes(), src_stats(), opt_stats(), errors(),
   optimized(), id(id),
   coal(*this), bbs(),
   target(t), vt(ex), ex(*this), root(),
   compute_interferences(),
-  has_alu_predication(), uses_gradients(), ngpr(), nstack() {}
+  has_alu_predication(), uses_gradients(), safe_math(), ngpr(), nstack() {}
 
 bool shader::assign_slot(alu_node* n, alu_node *slots[5]) {
 
@@ -61,7 +58,7 @@ bool shader::assign_slot(alu_node* n, alu_node *slots[5]) {
        return true;
 }
 
-void shader::add_gpr_values(vvec& vec, unsigned gpr, unsigned comp_mask,
+void shader::add_pinned_gpr_values(vvec& vec, unsigned gpr, unsigned comp_mask,
                             bool src) {
        unsigned chan = 0;
        while (comp_mask) {
@@ -72,6 +69,11 @@ void shader::add_gpr_values(vvec& vec, unsigned gpr, unsigned comp_mask,
                                v->gpr = v->pin_gpr = v->select;
                                v->fix();
                        }
+                       if (v->array && !v->array->gpr) {
+                               // if pinned value can be accessed with indirect addressing
+                               // pin the entire array to its original location
+                               v->array->gpr = v->array->base_gpr;
+                       }
                        vec.push_back(v);
                }
                comp_mask >>= 1;
@@ -199,7 +201,7 @@ void shader::add_input(unsigned gpr, bool preloaded, unsigned comp_mask) {
        i.comp_mask = comp_mask;
 
        if (preloaded) {
-               add_gpr_values(root->dst, gpr, comp_mask, true);
+               add_pinned_gpr_values(root->dst, gpr, comp_mask, true);
        }
 
 }
@@ -217,9 +219,9 @@ void shader::init_call_fs(cf_node* cf) {
        for(inputs_vec::const_iterator I = inputs.begin(),
                        E = inputs.end(); I != E; ++I, ++gpr) {
                if (!I->preloaded)
-                       add_gpr_values(cf->dst, gpr, I->comp_mask, false);
+                       add_pinned_gpr_values(cf->dst, gpr, I->comp_mask, false);
                else
-                       add_gpr_values(cf->src, gpr, I->comp_mask, true);
+                       add_pinned_gpr_values(cf->src, gpr, I->comp_mask, true);
        }
 }
 
@@ -238,26 +240,7 @@ void shader::set_undef(val_set& s) {
                v->gvn_source = undefined->gvn_source;
        }
 }
-/*
-void shader::transfer_pins(vvec& vv, vvec &sv) {
-       vvec::iterator SI = sv.begin();
-       for (vvec::iterator I = vv.begin(), E = vv.end(); I != E; ++I, ++SI) {
-               value *v = *I;
-               value *sv = *SI;
 
-               v->pin_gpr = sv->pin_gpr;
-
-               if (sv->is_chan_pinned()) {
-                       v->flags |= VLF_PIN_CHAN;
-                       sv->flags &= ~VLF_PIN_CHAN;
-               }
-               if (sv->is_reg_pinned()) {
-                       v->flags |= VLF_PIN_REG;
-                       sv->flags &= ~VLF_PIN_REG;
-               }
-       }
-}
-*/
 value* shader::create_value(value_kind k, sel_chan regid, unsigned ver) {
        value *v = val_pool.create(k, regid, ver);
        return v;
@@ -351,18 +334,7 @@ bb_node* shader::create_bb(unsigned id, unsigned loop_level) {
        all_nodes.push_back(n);
        return n;
 }
-/*
-void shader::prepare_regs(unsigned cnt) {
-       assert(!prep_regs_count);
-
-       for (unsigned i = 0; i < cnt*4; ++i) {
-               value *v = create_value(VLK_REG, i + 1, 0);
-               assert (v->uid == i + 1);
-       }
 
-       prep_regs_count = cnt;
-}
-*/
 value* shader::get_special_ro_value(unsigned sel) {
        return get_ro_value(special_ro_values, VLK_PARAM, sel);
 }
@@ -377,6 +349,11 @@ shader::~shader() {
        for (node_vec::iterator I = all_nodes.begin(), E = all_nodes.end();
                        I != E; ++I)
                (*I)->~node();
+
+       for (gpr_array_vec::iterator I = gpr_arrays.begin(), E = gpr_arrays.end();
+                       I != E; ++I) {
+               delete *I;
+       }
 }
 
 void shader::dump_ir() {
@@ -417,7 +394,7 @@ void shader::add_gpr_array(unsigned gpr_start, unsigned gpr_count,
                        gpr_array *a = new gpr_array(
                                        sel_chan(gpr_start, chan), gpr_count);
 
-                       SB_DUMP_PASS( cerr << "add_gpr_array: @" << a->base_gpr
+                       SB_DUMP_PASS( sblog << "add_gpr_array: @" << a->base_gpr
                                 << " [" << a->array_size << "]\n";
                        );
 
@@ -446,60 +423,12 @@ cf_node* shader::create_cf(unsigned op) {
 std::string shader::get_full_target_name() {
        std::string s = get_shader_target_name();
        s += "/";
-       s += get_hw_chip_name();
+       s += ctx.get_hw_chip_name();
        s += "/";
-       s += get_hw_class_name();
+       s += ctx.get_hw_class_name();
        return s;
 }
 
-const char* shader::get_hw_class_name() {
-       switch (ctx.hw_class) {
-#define TRANSLATE_HW_CLASS(c) case HW_CLASS_##c: return #c
-               TRANSLATE_HW_CLASS(R600);
-               TRANSLATE_HW_CLASS(R700);
-               TRANSLATE_HW_CLASS(EVERGREEN);
-               TRANSLATE_HW_CLASS(CAYMAN);
-#undef TRANSLATE_HW_CLASS
-               default:
-                       return "INVALID_CHIP_CLASS";
-       }
-}
-
-const char* shader::get_hw_chip_name() {
-       switch (ctx.hw_chip) {
-#define TRANSLATE_CHIP(c) case HW_CHIP_##c: return #c
-               TRANSLATE_CHIP(R600);
-               TRANSLATE_CHIP(RV610);
-               TRANSLATE_CHIP(RV630);
-               TRANSLATE_CHIP(RV670);
-               TRANSLATE_CHIP(RV620);
-               TRANSLATE_CHIP(RV635);
-               TRANSLATE_CHIP(RS780);
-               TRANSLATE_CHIP(RS880);
-               TRANSLATE_CHIP(RV770);
-               TRANSLATE_CHIP(RV730);
-               TRANSLATE_CHIP(RV710);
-               TRANSLATE_CHIP(RV740);
-               TRANSLATE_CHIP(CEDAR);
-               TRANSLATE_CHIP(REDWOOD);
-               TRANSLATE_CHIP(JUNIPER);
-               TRANSLATE_CHIP(CYPRESS);
-               TRANSLATE_CHIP(HEMLOCK);
-               TRANSLATE_CHIP(PALM);
-               TRANSLATE_CHIP(SUMO);
-               TRANSLATE_CHIP(SUMO2);
-               TRANSLATE_CHIP(BARTS);
-               TRANSLATE_CHIP(TURKS);
-               TRANSLATE_CHIP(CAICOS);
-               TRANSLATE_CHIP(CAYMAN);
-#undef TRANSLATE_CHIP
-
-               default:
-                       assert(!"unknown chip");
-                       return "INVALID_CHIP";
-       }
-}
-
 const char* shader::get_shader_target_name() {
        switch (target) {
                case TARGET_VS: return "VS";
@@ -557,6 +486,23 @@ alu_node* shader::clone(alu_node* n) {
        return c;
 }
 
+void shader::collect_stats(bool opt) {
+       if (!sb_context::dump_stat)
+               return;
+
+       shader_stats &s = opt ? opt_stats : src_stats;
+
+       s.shaders = 1;
+       s.ngpr = ngpr;
+       s.nstack = nstack;
+       s.collect(root);
+
+       if (opt)
+               ctx.opt_stats.accumulate(s);
+       else
+               ctx.src_stats.accumulate(s);
+}
+
 value* shader::get_ro_value(value_map& vm, value_kind vk, unsigned key) {
        value_map::iterator I = vm.find(key);
        if (I != vm.end())
@@ -657,4 +603,78 @@ sched_queue_id shader::get_queue_id(node* n) {
        }
 }
 
+void shader_stats::collect(node *n) {
+       if (n->is_alu_inst())
+               ++alu;
+       else if (n->is_fetch_inst())
+               ++fetch;
+       else if (n->is_container()) {
+               container_node *c = static_cast<container_node*>(n);
+
+               if (n->is_alu_group())
+                       ++alu_groups;
+               else if (n->is_alu_clause())
+                       ++alu_clauses;
+               else if (n->is_fetch_clause())
+                       ++fetch_clauses;
+               else if (n->is_cf_inst())
+                       ++cf;
+
+               if (!c->empty()) {
+                       for (node_iterator I = c->begin(), E = c->end(); I != E; ++I) {
+                               collect(*I);
+                       }
+               }
+       }
+}
+
+void shader_stats::accumulate(shader_stats& s) {
+       ++shaders;
+       ndw += s.ndw;
+       ngpr += s.ngpr;
+       nstack += s.nstack;
+
+       alu += s.alu;
+       alu_groups += s.alu_groups;
+       alu_clauses += s.alu_clauses;
+       fetch += s.fetch;
+       fetch_clauses += s.fetch_clauses;
+       cf += s.cf;
+}
+
+void shader_stats::dump() {
+       sblog << "dw:" << ndw << ", gpr:" << ngpr << ", stk:" << nstack
+                       << ", alu groups:" << alu_groups << ", alu clauses: " << alu_clauses
+                       << ", alu:" << alu << ", fetch:" << fetch
+                       << ", fetch clauses:" << fetch_clauses
+                       << ", cf:" << cf;
+
+       if (shaders > 1)
+               sblog << ", shaders:" << shaders;
+
+       sblog << "\n";
+}
+
+static void print_diff(unsigned d1, unsigned d2) {
+       if (d1)
+               sblog << ((int)d2 - (int)d1) * 100 / (int)d1 << "%";
+       else if (d2)
+               sblog << "N/A";
+       else
+               sblog << "0%";
+}
+
+void shader_stats::dump_diff(shader_stats& s) {
+       sblog << "dw:"; print_diff(ndw, s.ndw);
+       sblog << ", gpr:" ; print_diff(ngpr, s.ngpr);
+       sblog << ", stk:" ; print_diff(nstack, s.nstack);
+       sblog << ", alu groups:" ; print_diff(alu_groups, s.alu_groups);
+       sblog << ", alu clauses: " ; print_diff(alu_clauses, s.alu_clauses);
+       sblog << ", alu:" ; print_diff(alu, s.alu);
+       sblog << ", fetch:" ; print_diff(fetch, s.fetch);
+       sblog << ", fetch clauses:" ; print_diff(fetch_clauses, s.fetch_clauses);
+       sblog << ", cf:" ; print_diff(cf, s.cf);
+       sblog << "\n";
+}
+
 } // namespace r600_sb