Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2013 Vadim Girlin <vadimgirlin@gmail.com>
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * on the rights to use, copy, modify, merge, publish, distribute, sub
  8.  * license, and/or sell copies of the Software, and to permit persons to whom
  9.  * the Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  18.  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
  19.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  20.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  21.  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  22.  *
  23.  * Authors:
  24.  *      Vadim Girlin
  25.  */
  26.  
  27. #include "sb_bc.h"
  28. #include "sb_shader.h"
  29. #include "sb_pass.h"
  30.  
  31. namespace r600_sb {
  32.  
  33. static const char* chans = "xyzw01?_";
  34.  
  35. static const char* vec_bs[] = {
  36.                 "VEC_012", "VEC_021", "VEC_120", "VEC_102", "VEC_201", "VEC_210"
  37. };
  38.  
  39. static const char* scl_bs[] = {
  40.                 "SCL_210", "SCL_122", "SCL_212", "SCL_221"
  41. };
  42.  
  43.  
  44. bool bc_dump::visit(cf_node& n, bool enter) {
  45.         if (enter) {
  46.  
  47.                 id = n.bc.id << 1;
  48.  
  49.                 if ((n.bc.op_ptr->flags & CF_ALU) && n.bc.is_alu_extended()) {
  50.                         dump_dw(id, 2);
  51.                         id += 2;
  52.                         sblog << "\n";
  53.                 }
  54.  
  55.                 dump_dw(id, 2);
  56.                 dump(n);
  57.  
  58.                 if (n.bc.op_ptr->flags & CF_CLAUSE) {
  59.                         id = n.bc.addr << 1;
  60.                         new_group = 1;
  61.                 }
  62.         }
  63.         return true;
  64. }
  65.  
  66. bool bc_dump::visit(alu_node& n, bool enter) {
  67.         if (enter) {
  68.                 sblog << " ";
  69.                 dump_dw(id, 2);
  70.  
  71.                 if (new_group) {
  72.                         sblog.print_w(++group_index, 5);
  73.                         sblog << " ";
  74.                 } else
  75.                         sblog << "      ";
  76.  
  77.                 dump(n);
  78.                 id += 2;
  79.  
  80.                 new_group = n.bc.last;
  81.         } else {
  82.                 if (n.bc.last) {
  83.                         alu_group_node *g =
  84.                                         static_cast<alu_group_node*>(n.get_alu_group_node());
  85.                         assert(g);
  86.                         for (unsigned k = 0; k < g->literals.size(); ++k) {
  87.                                 sblog << " ";
  88.                                 dump_dw(id, 1);
  89.                                 id += 1;
  90.                                 sblog << "\n";
  91.                         }
  92.  
  93.                         id = (id + 1) & ~1u;
  94.                 }
  95.         }
  96.  
  97.         return false;
  98. }
  99.  
  100. bool bc_dump::visit(fetch_node& n, bool enter) {
  101.         if (enter) {
  102.                 sblog << " ";
  103.                 dump_dw(id, 3);
  104.                 dump(n);
  105.                 id += 4;
  106.         }
  107.         return false;
  108. }
  109.  
  110. static void fill_to(sb_ostringstream &s, int pos) {
  111.         int l = s.str().length();
  112.         if (l < pos)
  113.                 s << std::string(pos-l, ' ');
  114. }
  115.  
  116. void bc_dump::dump(cf_node& n) {
  117.         sb_ostringstream s;
  118.         s << n.bc.op_ptr->name;
  119.  
  120.         if (n.bc.op_ptr->flags & CF_EXP) {
  121.                 static const char *exp_type[] = {"PIXEL", "POS  ", "PARAM"};
  122.  
  123.                 fill_to(s, 18);
  124.                 s << " " << exp_type[n.bc.type] << " ";
  125.  
  126.                 if (n.bc.burst_count) {
  127.                         sb_ostringstream s2;
  128.                         s2 << n.bc.array_base << "-" << n.bc.array_base + n.bc.burst_count;
  129.                         s.print_wl(s2.str(), 5);
  130.                         s << " R" << n.bc.rw_gpr << "-" <<
  131.                                         n.bc.rw_gpr + n.bc.burst_count << ".";
  132.                 } else {
  133.                         s.print_wl(n.bc.array_base, 5);
  134.                         s << " R" << n.bc.rw_gpr << ".";
  135.                 }
  136.  
  137.                 for (int k = 0; k < 4; ++k)
  138.                         s << chans[n.bc.sel[k]];
  139.  
  140.         } else if (n.bc.op_ptr->flags & CF_MEM) {
  141.                 static const char *exp_type[] = {"WRITE", "WRITE_IND", "WRITE_ACK",
  142.                                 "WRITE_IND_ACK"};
  143.                 fill_to(s, 18);
  144.                 s << " " << exp_type[n.bc.type] << " ";
  145.                 s.print_wl(n.bc.array_base, 5);
  146.                 s << " R" << n.bc.rw_gpr << ".";
  147.                 for (int k = 0; k < 4; ++k)
  148.                         s << ((n.bc.comp_mask & (1 << k)) ? chans[k] : '_');
  149.  
  150.                 if ((n.bc.op_ptr->flags & CF_RAT) && (n.bc.type & 1)) {
  151.                         s << ", @R" << n.bc.index_gpr << ".xyz";
  152.                 }
  153.                 if ((n.bc.op_ptr->flags & CF_MEM) && (n.bc.type & 1)) {
  154.                         s << ", @R" << n.bc.index_gpr << ".x";
  155.                 }
  156.  
  157.                 s << "  ES:" << n.bc.elem_size;
  158.  
  159.         } else {
  160.  
  161.                 if (n.bc.op_ptr->flags & CF_CLAUSE) {
  162.                         s << " " << n.bc.count+1;
  163.                 }
  164.  
  165.                 s << " @" << (n.bc.addr << 1);
  166.  
  167.                 if (n.bc.op_ptr->flags & CF_ALU) {
  168.                         static const char *index_mode[] = {"", " CF_INDEX_0", " CF_INDEX_1"};
  169.  
  170.                         for (int k = 0; k < 4; ++k) {
  171.                                 bc_kcache &kc = n.bc.kc[k];
  172.                                 if (kc.mode) {
  173.                                         s << " KC" << k << "[CB" << kc.bank << ":" <<
  174.                                                         (kc.addr << 4) << "-" <<
  175.                                                         (((kc.addr + kc.mode) << 4) - 1) << index_mode[kc.index_mode] << "]";
  176.                                 }
  177.                         }
  178.                 }
  179.  
  180.                 if (n.bc.cond)
  181.                         s << " CND:" << n.bc.cond;
  182.  
  183.                 if (n.bc.pop_count)
  184.                         s << " POP:" << n.bc.pop_count;
  185.         }
  186.  
  187.         if (!n.bc.barrier)
  188.                 s << "  NO_BARRIER";
  189.  
  190.         if (n.bc.valid_pixel_mode)
  191.                 s << "  VPM";
  192.  
  193.         if (n.bc.whole_quad_mode)
  194.                 s << "  WQM";
  195.  
  196.         if (n.bc.end_of_program)
  197.                 s << "  EOP";
  198.  
  199.         sblog << s.str() << "\n";
  200. }
  201.  
  202.  
  203. static void print_sel(sb_ostream &s, int sel, int rel, int index_mode,
  204.                       int need_brackets) {
  205.         if (rel && index_mode >= 5 && sel < 128)
  206.                 s << "G";
  207.         if (rel || need_brackets) {
  208.                 s << "[";
  209.         }
  210.         s << sel;
  211.         if (rel) {
  212.                 if (index_mode == 0 || index_mode == 6)
  213.                         s << "+AR";
  214.                 else if (index_mode == 4)
  215.                         s << "+AL";
  216.         }
  217.         if (rel || need_brackets) {
  218.                 s << "]";
  219.         }
  220. }
  221.  
  222. static void print_dst(sb_ostream &s, bc_alu &alu)
  223. {
  224.         unsigned sel = alu.dst_gpr;
  225.         char reg_char = 'R';
  226.         if (sel >= 128 - 4) { // clause temporary gpr
  227.                 sel -= 128 - 4;
  228.                 reg_char = 'T';
  229.         }
  230.  
  231.         if (alu.write_mask || alu.op_ptr->src_count == 3) {
  232.                 s << reg_char;
  233.                 print_sel(s, sel, alu.dst_rel, alu.index_mode, 0);
  234.         } else {
  235.                 s << "__";
  236.         }
  237.         s << ".";
  238.         s << chans[alu.dst_chan];
  239. }
  240.  
  241. static void print_src(sb_ostream &s, bc_alu &alu, unsigned idx)
  242. {
  243.         bc_alu_src *src = &alu.src[idx];
  244.         unsigned sel = src->sel, need_sel = 1, need_chan = 1, need_brackets = 0;
  245.  
  246.         if (src->neg)
  247.                 s <<"-";
  248.         if (src->abs)
  249.                 s <<"|";
  250.  
  251.         if (sel < 128 - 4) {
  252.                 s << "R";
  253.         } else if (sel < 128) {
  254.                 s << "T";
  255.                 sel -= 128 - 4;
  256.         } else if (sel < 160) {
  257.                 s << "KC0";
  258.                 need_brackets = 1;
  259.                 sel -= 128;
  260.         } else if (sel < 192) {
  261.                 s << "KC1";
  262.                 need_brackets = 1;
  263.                 sel -= 160;
  264.         } else if (sel >= 448) {
  265.                 s << "Param";
  266.                 sel -= 448;
  267.         } else if (sel >= 288) {
  268.                 s << "KC3";
  269.                 need_brackets = 1;
  270.                 sel -= 288;
  271.         } else if (sel >= 256) {
  272.                 s << "KC2";
  273.                 need_brackets = 1;
  274.                 sel -= 256;
  275.         } else {
  276.                 need_sel = 0;
  277.                 need_chan = 0;
  278.                 switch (sel) {
  279.                 case ALU_SRC_PS:
  280.                         s << "PS";
  281.                         break;
  282.                 case ALU_SRC_PV:
  283.                         s << "PV";
  284.                         need_chan = 1;
  285.                         break;
  286.                 case ALU_SRC_LITERAL:
  287.                         s << "[0x";
  288.                         s.print_zw_hex(src->value.u, 8);
  289.                         s << " " << src->value.f << "]";
  290.                         need_chan = 1;
  291.                         break;
  292.                 case ALU_SRC_0_5:
  293.                         s << "0.5";
  294.                         break;
  295.                 case ALU_SRC_M_1_INT:
  296.                         s << "-1";
  297.                         break;
  298.                 case ALU_SRC_1_INT:
  299.                         s << "1";
  300.                         break;
  301.                 case ALU_SRC_1:
  302.                         s << "1.0";
  303.                         break;
  304.                 case ALU_SRC_0:
  305.                         s << "0";
  306.                         break;
  307.                 default:
  308.                         s << "??IMM_" <<  sel;
  309.                         break;
  310.                 }
  311.         }
  312.  
  313.         if (need_sel)
  314.                 print_sel(s, sel, src->rel, alu.index_mode, need_brackets);
  315.  
  316.         if (need_chan) {
  317.                 s << "." << chans[src->chan];
  318.         }
  319.  
  320.         if (src->abs)
  321.                 s << "|";
  322. }
  323. void bc_dump::dump(alu_node& n) {
  324.         sb_ostringstream s;
  325.         static const char *omod_str[] = {"","*2","*4","/2"};
  326.         static const char *slots = "xyzwt";
  327.  
  328.         s << (n.bc.update_exec_mask ? "M" : " ");
  329.         s << (n.bc.update_pred ? "P" : " ");
  330.         s << " ";
  331.         s << (n.bc.pred_sel>=2 ? (n.bc.pred_sel == 2 ? "0" : "1") : " ");
  332.         s << " ";
  333.  
  334.         s << slots[n.bc.slot] << ": ";
  335.  
  336.         s << n.bc.op_ptr->name << omod_str[n.bc.omod] << (n.bc.clamp ? "_sat" : "");
  337.         fill_to(s, 26);
  338.         s << " ";
  339.  
  340.         print_dst(s, n.bc);
  341.         for (int k = 0; k < n.bc.op_ptr->src_count; ++k) {
  342.                 s << (k ? ", " : ",  ");
  343.                 print_src(s, n.bc, k);
  344.         }
  345.  
  346.         if (n.bc.bank_swizzle) {
  347.                 fill_to(s, 55);
  348.                 if (n.bc.slot == SLOT_TRANS)
  349.                         s << "  " << scl_bs[n.bc.bank_swizzle];
  350.                 else
  351.                         s << "  " << vec_bs[n.bc.bank_swizzle];
  352.         }
  353.  
  354.         sblog << s.str() << "\n";
  355. }
  356.  
  357. int bc_dump::init() {
  358.         sb_ostringstream s;
  359.         s << "===== SHADER #" << sh.id;
  360.  
  361.         if (sh.optimized)
  362.                 s << " OPT";
  363.  
  364.         s << " ";
  365.  
  366.         std::string target = std::string(" ") +
  367.                         sh.get_full_target_name() + " =====";
  368.  
  369.         while (s.str().length() + target.length() < 80)
  370.                 s << "=";
  371.  
  372.         s << target;
  373.  
  374.         sblog << "\n" << s.str() << "\n";
  375.  
  376.         s.clear();
  377.  
  378.         if (bc_data) {
  379.                 s << "===== " << ndw << " dw ===== " << sh.ngpr
  380.                                 << " gprs ===== " << sh.nstack << " stack ";
  381.         }
  382.  
  383.         while (s.str().length() < 80)
  384.                 s << "=";
  385.  
  386.         sblog << s.str() << "\n";
  387.  
  388.         return 0;
  389. }
  390.  
  391. int bc_dump::done() {
  392.         sb_ostringstream s;
  393.         s << "===== SHADER_END ";
  394.  
  395.         while (s.str().length() < 80)
  396.                 s << "=";
  397.  
  398.         sblog << s.str() << "\n\n";
  399.  
  400.         return 0;
  401. }
  402.  
  403. bc_dump::bc_dump(shader& s, bytecode* bc)  :
  404.         vpass(s), bc_data(), ndw(), id(),
  405.         new_group(), group_index() {
  406.  
  407.         if (bc) {
  408.                 bc_data = bc->data();
  409.                 ndw = bc->ndw();
  410.         }
  411. }
  412.  
  413. void bc_dump::dump(fetch_node& n) {
  414.         sb_ostringstream s;
  415.         static const char * fetch_type[] = {"VERTEX", "INSTANCE", ""};
  416.  
  417.         s << n.bc.op_ptr->name;
  418.         fill_to(s, 20);
  419.  
  420.         s << "R";
  421.         print_sel(s, n.bc.dst_gpr, n.bc.dst_rel, INDEX_LOOP, 0);
  422.         s << ".";
  423.         for (int k = 0; k < 4; ++k)
  424.                 s << chans[n.bc.dst_sel[k]];
  425.         s << ", ";
  426.  
  427.         s << "R";
  428.         print_sel(s, n.bc.src_gpr, n.bc.src_rel, INDEX_LOOP, 0);
  429.         s << ".";
  430.  
  431.         unsigned vtx = n.bc.op_ptr->flags & FF_VTX;
  432.         unsigned num_src_comp = vtx ? ctx.is_cayman() ? 2 : 1 : 4;
  433.  
  434.         for (unsigned k = 0; k < num_src_comp; ++k)
  435.                 s << chans[n.bc.src_sel[k]];
  436.  
  437.         if (vtx && n.bc.offset[0]) {
  438.                 s << " + " << n.bc.offset[0] << "b ";
  439.         }
  440.  
  441.         s << ",   RID:" << n.bc.resource_id;
  442.  
  443.         if (vtx) {
  444.                 s << "  " << fetch_type[n.bc.fetch_type];
  445.                 if (!ctx.is_cayman() && n.bc.mega_fetch_count)
  446.                         s << " MFC:" << n.bc.mega_fetch_count;
  447.                 if (n.bc.fetch_whole_quad)
  448.                         s << " FWQ";
  449.                 if (ctx.is_egcm() && n.bc.resource_index_mode)
  450.                         s << " RIM:SQ_CF_INDEX_" << n.bc.resource_index_mode;
  451.                 if (ctx.is_egcm() && n.bc.sampler_index_mode)
  452.                         s << " SID:SQ_CF_INDEX_" << n.bc.sampler_index_mode;
  453.  
  454.                 s << " UCF:" << n.bc.use_const_fields
  455.                                 << " FMT(DTA:" << n.bc.data_format
  456.                                 << " NUM:" << n.bc.num_format_all
  457.                                 << " COMP:" << n.bc.format_comp_all
  458.                                 << " MODE:" << n.bc.srf_mode_all << ")";
  459.         } else {
  460.                 s << ", SID:" << n.bc.sampler_id;
  461.                 if (n.bc.lod_bias)
  462.                         s << " LB:" << n.bc.lod_bias;
  463.                 s << " CT:";
  464.                 for (unsigned k = 0; k < 4; ++k)
  465.                         s << (n.bc.coord_type[k] ? "N" : "U");
  466.                 for (unsigned k = 0; k < 3; ++k)
  467.                         if (n.bc.offset[k])
  468.                                 s << " O" << chans[k] << ":" << n.bc.offset[k];
  469.         }
  470.  
  471.         sblog << s.str() << "\n";
  472. }
  473.  
  474. void bc_dump::dump_dw(unsigned dw_id, unsigned count) {
  475.         if (!bc_data)
  476.                 return;
  477.  
  478.         assert(dw_id + count <= ndw);
  479.  
  480.         sblog.print_zw(dw_id, 4);
  481.         sblog << "  ";
  482.         while (count--) {
  483.                 sblog.print_zw_hex(bc_data[dw_id++], 8);
  484.                 sblog << " ";
  485.         }
  486. }
  487.  
  488. } // namespace r600_sb
  489.