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. bc_builder::bc_builder(shader &s)
  34.         : sh(s), ctx(s.get_ctx()), bb(ctx.hw_class_bit()), error(0) {}
  35.  
  36. int bc_builder::build() {
  37.  
  38.         container_node *root = sh.root;
  39.         int cf_cnt = 0;
  40.  
  41.         // FIXME reserve total size to avoid reallocs
  42.  
  43.         for (node_iterator it = root->begin(), end = root->end();
  44.                         it != end; ++it) {
  45.  
  46.                 cf_node *cf = static_cast<cf_node*>(*it);
  47.                 assert(cf->is_cf_inst() || cf->is_alu_clause() || cf->is_fetch_clause());
  48.  
  49.                 cf_op_flags flags = (cf_op_flags)cf->bc.op_ptr->flags;
  50.  
  51.                 cf->bc.id = cf_cnt++;
  52.  
  53.                 if (flags & CF_ALU) {
  54.                         if (cf->bc.is_alu_extended())
  55.                                 cf_cnt++;
  56.                 }
  57.         }
  58.  
  59.         bb.set_size(cf_cnt << 1);
  60.         bb.seek(cf_cnt << 1);
  61.  
  62.         unsigned cf_pos = 0;
  63.  
  64.         for (node_iterator I = root->begin(), end = root->end();
  65.                         I != end; ++I) {
  66.  
  67.                 cf_node *cf = static_cast<cf_node*>(*I);
  68.                 cf_op_flags flags = (cf_op_flags)cf->bc.op_ptr->flags;
  69.  
  70.                 if (flags & CF_ALU) {
  71.                         bb.seek(bb.ndw());
  72.                         cf->bc.addr = bb.ndw() >> 1;
  73.                         build_alu_clause(cf);
  74.                         cf->bc.count = (bb.ndw() >> 1) - cf->bc.addr - 1;
  75.                 } else if (flags & CF_FETCH) {
  76.                         bb.align(4);
  77.                         bb.seek(bb.ndw());
  78.                         cf->bc.addr = bb.ndw() >> 1;
  79.                         build_fetch_clause(cf);
  80.                         cf->bc.count = (((bb.ndw() >> 1) - cf->bc.addr) >> 1) - 1;
  81.                 } else if (cf->jump_target) {
  82.                         cf->bc.addr = cf->jump_target->bc.id;
  83.                         if (cf->jump_after_target)
  84.                                 cf->bc.addr += 1;
  85.                 }
  86.  
  87.                 bb.seek(cf_pos);
  88.                 build_cf(cf);
  89.                 cf_pos = bb.get_pos();
  90.         }
  91.  
  92.         return 0;
  93. }
  94.  
  95. int bc_builder::build_alu_clause(cf_node* n) {
  96.         for (node_iterator I = n->begin(),      E = n->end();
  97.                         I != E; ++I) {
  98.  
  99.                 alu_group_node *g = static_cast<alu_group_node*>(*I);
  100.                 assert(g->is_valid());
  101.  
  102.                 build_alu_group(g);
  103.         }
  104.         return 0;
  105. }
  106.  
  107. int bc_builder::build_alu_group(alu_group_node* n) {
  108.  
  109.         for (node_iterator I = n->begin(),      E = n->end();
  110.                         I != E; ++I) {
  111.  
  112.                 alu_node *a = static_cast<alu_node*>(*I);
  113.                 assert(a->is_valid());
  114.                 build_alu(a);
  115.         }
  116.  
  117.         for(int i = 0, ls = n->literals.size(); i < ls; ++i) {
  118.                 bb << n->literals.at(i).u;
  119.         }
  120.  
  121.         bb.align(2);
  122.         bb.seek(bb.ndw());
  123.  
  124.         return 0;
  125. }
  126.  
  127. int bc_builder::build_fetch_clause(cf_node* n) {
  128.         for (node_iterator I = n->begin(), E = n->end();
  129.                         I != E; ++I) {
  130.                 fetch_node *f = static_cast<fetch_node*>(*I);
  131.  
  132.                 if (f->bc.op_ptr->flags & FF_VTX)
  133.                         build_fetch_vtx(f);
  134.                 else
  135.                         build_fetch_tex(f);
  136.         }
  137.         return 0;
  138. }
  139.  
  140.  
  141. int bc_builder::build_cf(cf_node* n) {
  142.         const bc_cf &bc = n->bc;
  143.         const cf_op_info *cfop = bc.op_ptr;
  144.  
  145.         if (cfop->flags & CF_ALU)
  146.                 return build_cf_alu(n);
  147.         if (cfop->flags & (CF_EXP | CF_MEM))
  148.                 return build_cf_exp(n);
  149.  
  150.         if (ctx.is_egcm()) {
  151.                 bb << CF_WORD0_EGCM()
  152.                                 .ADDR(bc.addr)
  153.                                 .JUMPTABLE_SEL(bc.jumptable_sel);
  154.  
  155.                 if (ctx.is_evergreen())
  156.  
  157.                         bb << CF_WORD1_EG()
  158.                                         .BARRIER(bc.barrier)
  159.                                         .CF_CONST(bc.cf_const)
  160.                                         .CF_INST(ctx.cf_opcode(bc.op))
  161.                                         .COND(bc.cond)
  162.                                         .COUNT(bc.count)
  163.                                         .END_OF_PROGRAM(bc.end_of_program)
  164.                                         .POP_COUNT(bc.pop_count)
  165.                                         .VALID_PIXEL_MODE(bc.valid_pixel_mode)
  166.                                         .WHOLE_QUAD_MODE(bc.whole_quad_mode);
  167.  
  168.                 else //cayman
  169.  
  170.                         bb << CF_WORD1_CM()
  171.                                         .BARRIER(bc.barrier)
  172.                                         .CF_CONST(bc.cf_const)
  173.                                         .CF_INST(ctx.cf_opcode(bc.op))
  174.                                         .COND(bc.cond)
  175.                                         .COUNT(bc.count)
  176.                                         .POP_COUNT(bc.pop_count)
  177.                                         .VALID_PIXEL_MODE(bc.valid_pixel_mode);
  178.         } else {
  179.                 bb << CF_WORD0_R6R7()
  180.                                 .ADDR(bc.addr);
  181.  
  182.                 assert(bc.count < ctx.max_fetch);
  183.  
  184.                 bb << CF_WORD1_R6R7()
  185.                                 .BARRIER(bc.barrier)
  186.                                 .CALL_COUNT(bc.call_count)
  187.                                 .CF_CONST(bc.cf_const)
  188.                                 .CF_INST(ctx.cf_opcode(bc.op))
  189.                                 .COND(bc.cond)
  190.                                 .COUNT(bc.count & 7)
  191.                                 .COUNT_3(bc.count >> 3)
  192.                                 .END_OF_PROGRAM(bc.end_of_program)
  193.                                 .POP_COUNT(bc.pop_count)
  194.                                 .VALID_PIXEL_MODE(bc.valid_pixel_mode)
  195.                                 .WHOLE_QUAD_MODE(bc.whole_quad_mode);
  196.         }
  197.  
  198.         return 0;
  199. }
  200.  
  201. int bc_builder::build_cf_alu(cf_node* n) {
  202.         const bc_cf &bc = n->bc;
  203.  
  204.         assert(bc.count < 128);
  205.  
  206.         if (n->bc.is_alu_extended()) {
  207.                 assert(ctx.is_egcm());
  208.  
  209.                 bb << CF_ALU_WORD0_EXT_EGCM()
  210.                                 .KCACHE_BANK2(bc.kc[2].bank)
  211.                                 .KCACHE_BANK3(bc.kc[3].bank)
  212.                                 .KCACHE_BANK_INDEX_MODE0(bc.kc[0].index_mode)
  213.                                 .KCACHE_BANK_INDEX_MODE1(bc.kc[1].index_mode)
  214.                                 .KCACHE_BANK_INDEX_MODE2(bc.kc[2].index_mode)
  215.                                 .KCACHE_BANK_INDEX_MODE3(bc.kc[3].index_mode)
  216.                                 .KCACHE_MODE2(bc.kc[2].mode);
  217.  
  218.                 bb << CF_ALU_WORD1_EXT_EGCM()
  219.                                 .BARRIER(bc.barrier)
  220.                                 .CF_INST(ctx.cf_opcode(CF_OP_ALU_EXT))
  221.                                 .KCACHE_ADDR2(bc.kc[2].addr)
  222.                                 .KCACHE_ADDR3(bc.kc[3].addr)
  223.                                 .KCACHE_MODE3(bc.kc[3].mode);
  224.         }
  225.  
  226.         bb << CF_ALU_WORD0_ALL()
  227.                         .ADDR(bc.addr)
  228.                         .KCACHE_BANK0(bc.kc[0].bank)
  229.                         .KCACHE_BANK1(bc.kc[1].bank)
  230.                         .KCACHE_MODE0(bc.kc[0].mode);
  231.  
  232.         assert(bc.count < 128);
  233.  
  234.         if (ctx.is_r600())
  235.                 bb << CF_ALU_WORD1_R6()
  236.                                 .BARRIER(bc.barrier)
  237.                                 .CF_INST(ctx.cf_opcode(bc.op))
  238.                                 .COUNT(bc.count)
  239.                                 .KCACHE_ADDR0(bc.kc[0].addr)
  240.                                 .KCACHE_ADDR1(bc.kc[1].addr)
  241.                                 .KCACHE_MODE1(bc.kc[1].mode)
  242.                                 .USES_WATERFALL(bc.uses_waterfall)
  243.                                 .WHOLE_QUAD_MODE(bc.whole_quad_mode);
  244.         else
  245.                 bb << CF_ALU_WORD1_R7EGCM()
  246.                                 .ALT_CONST(bc.alt_const)
  247.                                 .BARRIER(bc.barrier)
  248.                                 .CF_INST(ctx.cf_opcode(bc.op))
  249.                                 .COUNT(bc.count)
  250.                                 .KCACHE_ADDR0(bc.kc[0].addr)
  251.                                 .KCACHE_ADDR1(bc.kc[1].addr)
  252.                                 .KCACHE_MODE1(bc.kc[1].mode)
  253.                                 .WHOLE_QUAD_MODE(bc.whole_quad_mode);
  254.  
  255.         return 0;
  256. }
  257.  
  258. int bc_builder::build_cf_exp(cf_node* n) {
  259.         const bc_cf &bc = n->bc;
  260.         const cf_op_info *cfop = bc.op_ptr;
  261.  
  262.         if (cfop->flags & CF_RAT) {
  263.                 assert(ctx.is_egcm());
  264.  
  265.                 bb << CF_ALLOC_EXPORT_WORD0_RAT_EGCM()
  266.                                 .ELEM_SIZE(bc.elem_size)
  267.                                 .INDEX_GPR(bc.index_gpr)
  268.                                 .RAT_ID(bc.rat_id)
  269.                                 .RAT_INDEX_MODE(bc.rat_index_mode)
  270.                                 .RAT_INST(bc.rat_inst)
  271.                                 .RW_GPR(bc.rw_gpr)
  272.                                 .RW_REL(bc.rw_rel)
  273.                                 .TYPE(bc.type);
  274.         } else {
  275.  
  276.                 bb << CF_ALLOC_EXPORT_WORD0_ALL()
  277.                                         .ARRAY_BASE(bc.array_base)
  278.                                         .ELEM_SIZE(bc.elem_size)
  279.                                         .INDEX_GPR(bc.index_gpr)
  280.                                         .RW_GPR(bc.rw_gpr)
  281.                                         .RW_REL(bc.rw_rel)
  282.                                         .TYPE(bc.type);
  283.         }
  284.  
  285.         if (cfop->flags & CF_EXP) {
  286.  
  287.                 if (!ctx.is_egcm())
  288.                         bb << CF_ALLOC_EXPORT_WORD1_SWIZ_R6R7()
  289.                                         .BARRIER(bc.barrier)
  290.                                         .BURST_COUNT(bc.burst_count)
  291.                                         .CF_INST(ctx.cf_opcode(bc.op))
  292.                                         .END_OF_PROGRAM(bc.end_of_program)
  293.                                         .SEL_X(bc.sel[0])
  294.                                         .SEL_Y(bc.sel[1])
  295.                                         .SEL_Z(bc.sel[2])
  296.                                         .SEL_W(bc.sel[3])
  297.                                         .VALID_PIXEL_MODE(bc.valid_pixel_mode)
  298.                                         .WHOLE_QUAD_MODE(bc.whole_quad_mode);
  299.  
  300.                 else if (ctx.is_evergreen())
  301.                         bb << CF_ALLOC_EXPORT_WORD1_SWIZ_EG()
  302.                                         .BARRIER(bc.barrier)
  303.                                         .BURST_COUNT(bc.burst_count)
  304.                                         .CF_INST(ctx.cf_opcode(bc.op))
  305.                                         .END_OF_PROGRAM(bc.end_of_program)
  306.                                         .MARK(bc.mark)
  307.                                         .SEL_X(bc.sel[0])
  308.                                         .SEL_Y(bc.sel[1])
  309.                                         .SEL_Z(bc.sel[2])
  310.                                         .SEL_W(bc.sel[3])
  311.                                         .VALID_PIXEL_MODE(bc.valid_pixel_mode);
  312.  
  313.                 else // cayman
  314.                         bb << CF_ALLOC_EXPORT_WORD1_SWIZ_CM()
  315.                                         .BARRIER(bc.barrier)
  316.                                         .BURST_COUNT(bc.burst_count)
  317.                                         .CF_INST(ctx.cf_opcode(bc.op))
  318.                                         .MARK(bc.mark)
  319.                                         .SEL_X(bc.sel[0])
  320.                                         .SEL_Y(bc.sel[1])
  321.                                         .SEL_Z(bc.sel[2])
  322.                                         .SEL_W(bc.sel[3])
  323.                                         .VALID_PIXEL_MODE(bc.valid_pixel_mode);
  324.  
  325.         } else if (cfop->flags & CF_MEM) {
  326.                 return build_cf_mem(n);
  327.         }
  328.  
  329.         return 0;
  330. }
  331.  
  332. int bc_builder::build_cf_mem(cf_node* n) {
  333.         const bc_cf &bc = n->bc;
  334.  
  335.         if (!ctx.is_egcm())
  336.                 bb << CF_ALLOC_EXPORT_WORD1_BUF_R6R7()
  337.                                 .ARRAY_SIZE(bc.array_size)
  338.                                 .BARRIER(bc.barrier)
  339.                                 .BURST_COUNT(bc.burst_count)
  340.                                 .CF_INST(ctx.cf_opcode(bc.op))
  341.                                 .COMP_MASK(bc.comp_mask)
  342.                                 .END_OF_PROGRAM(bc.end_of_program)
  343.                                 .VALID_PIXEL_MODE(bc.valid_pixel_mode)
  344.                                 .WHOLE_QUAD_MODE(bc.whole_quad_mode);
  345.  
  346.         else if (ctx.is_evergreen())
  347.                 bb << CF_ALLOC_EXPORT_WORD1_BUF_EG()
  348.                                 .ARRAY_SIZE(bc.array_size)
  349.                                 .BARRIER(bc.barrier)
  350.                                 .BURST_COUNT(bc.burst_count)
  351.                                 .CF_INST(ctx.cf_opcode(bc.op))
  352.                                 .COMP_MASK(bc.comp_mask)
  353.                                 .END_OF_PROGRAM(bc.end_of_program)
  354.                                 .MARK(bc.mark)
  355.                                 .VALID_PIXEL_MODE(bc.valid_pixel_mode);
  356.  
  357.         else // cayman
  358.                 bb << CF_ALLOC_EXPORT_WORD1_BUF_CM()
  359.                 .ARRAY_SIZE(bc.array_size)
  360.                 .BARRIER(bc.barrier)
  361.                 .BURST_COUNT(bc.burst_count)
  362.                 .CF_INST(ctx.cf_opcode(bc.op))
  363.                 .COMP_MASK(bc.comp_mask)
  364.                 .MARK(bc.mark)
  365.                 .VALID_PIXEL_MODE(bc.valid_pixel_mode);
  366.  
  367.         return 0;
  368. }
  369.  
  370. int bc_builder::build_alu(alu_node* n) {
  371.         const bc_alu &bc = n->bc;
  372.         const alu_op_info *aop = bc.op_ptr;
  373.  
  374.         bb << ALU_WORD0_ALL()
  375.                         .INDEX_MODE(bc.index_mode)
  376.                         .LAST(bc.last)
  377.                         .PRED_SEL(bc.pred_sel)
  378.                         .SRC0_SEL(bc.src[0].sel)
  379.                         .SRC0_CHAN(bc.src[0].chan)
  380.                         .SRC0_NEG(bc.src[0].neg)
  381.                         .SRC0_REL(bc.src[0].rel)
  382.                         .SRC1_SEL(bc.src[1].sel)
  383.                         .SRC1_CHAN(bc.src[1].chan)
  384.                         .SRC1_NEG(bc.src[1].neg)
  385.                         .SRC1_REL(bc.src[1].rel);
  386.  
  387.         if (aop->src_count<3) {
  388.                 if (ctx.is_r600())
  389.                         bb << ALU_WORD1_OP2_R6()
  390.                                         .ALU_INST(ctx.alu_opcode(bc.op))
  391.                                         .BANK_SWIZZLE(bc.bank_swizzle)
  392.                                         .CLAMP(bc.clamp)
  393.                                         .DST_GPR(bc.dst_gpr)
  394.                                         .DST_CHAN(bc.dst_chan)
  395.                                         .DST_REL(bc.dst_rel)
  396.                                         .FOG_MERGE(bc.fog_merge)
  397.                                         .OMOD(bc.omod)
  398.                                         .SRC0_ABS(bc.src[0].abs)
  399.                                         .SRC1_ABS(bc.src[1].abs)
  400.                                         .UPDATE_EXEC_MASK(bc.update_exec_mask)
  401.                                         .UPDATE_PRED(bc.update_pred)
  402.                                         .WRITE_MASK(bc.write_mask);
  403.                 else {
  404.  
  405.                         if (ctx.is_cayman() && (aop->flags & AF_MOVA)) {
  406.  
  407.                                 bb << ALU_WORD1_OP2_MOVA_CM()
  408.                                                 .ALU_INST(ctx.alu_opcode(bc.op))
  409.                                                 .BANK_SWIZZLE(bc.bank_swizzle)
  410.                                                 .CLAMP(bc.clamp)
  411.                                                 .MOVA_DST(bc.dst_gpr)
  412.                                                 .DST_CHAN(bc.dst_chan)
  413.                                                 .DST_REL(bc.dst_rel)
  414.                                                 .OMOD(bc.omod)
  415.                                                 .UPDATE_EXEC_MASK(bc.update_exec_mask)
  416.                                                 .UPDATE_PRED(bc.update_pred)
  417.                                                 .WRITE_MASK(bc.write_mask)
  418.                                                 .SRC0_ABS(bc.src[0].abs)
  419.                                                 .SRC1_ABS(bc.src[1].abs);
  420.  
  421.                         } else if (ctx.is_cayman() && (aop->flags & (AF_PRED|AF_KILL))) {
  422.                                 bb << ALU_WORD1_OP2_EXEC_MASK_CM()
  423.                                                 .ALU_INST(ctx.alu_opcode(bc.op))
  424.                                                 .BANK_SWIZZLE(bc.bank_swizzle)
  425.                                                 .CLAMP(bc.clamp)
  426.                                                 .DST_CHAN(bc.dst_chan)
  427.                                                 .DST_REL(bc.dst_rel)
  428.                                                 .EXECUTE_MASK_OP(bc.omod)
  429.                                                 .UPDATE_EXEC_MASK(bc.update_exec_mask)
  430.                                                 .UPDATE_PRED(bc.update_pred)
  431.                                                 .WRITE_MASK(bc.write_mask)
  432.                                                 .SRC0_ABS(bc.src[0].abs)
  433.                                                 .SRC1_ABS(bc.src[1].abs);
  434.  
  435.                         } else
  436.                                 bb << ALU_WORD1_OP2_R7EGCM()
  437.                                                 .ALU_INST(ctx.alu_opcode(bc.op))
  438.                                                 .BANK_SWIZZLE(bc.bank_swizzle)
  439.                                                 .CLAMP(bc.clamp)
  440.                                                 .DST_GPR(bc.dst_gpr)
  441.                                                 .DST_CHAN(bc.dst_chan)
  442.                                                 .DST_REL(bc.dst_rel)
  443.                                                 .OMOD(bc.omod)
  444.                                                 .UPDATE_EXEC_MASK(bc.update_exec_mask)
  445.                                                 .UPDATE_PRED(bc.update_pred)
  446.                                                 .WRITE_MASK(bc.write_mask)
  447.                                                 .SRC0_ABS(bc.src[0].abs)
  448.                                                 .SRC1_ABS(bc.src[1].abs);
  449.  
  450.                 }
  451.         } else
  452.                 bb << ALU_WORD1_OP3_ALL()
  453.                                 .ALU_INST(ctx.alu_opcode(bc.op))
  454.                                 .BANK_SWIZZLE(bc.bank_swizzle)
  455.                                 .CLAMP(bc.clamp)
  456.                                 .DST_GPR(bc.dst_gpr)
  457.                                 .DST_CHAN(bc.dst_chan)
  458.                                 .DST_REL(bc.dst_rel)
  459.                                 .SRC2_SEL(bc.src[2].sel)
  460.                                 .SRC2_CHAN(bc.src[2].chan)
  461.                                 .SRC2_NEG(bc.src[2].neg)
  462.                                 .SRC2_REL(bc.src[2].rel);
  463.         return 0;
  464. }
  465.  
  466. int bc_builder::build_fetch_tex(fetch_node* n) {
  467.         const bc_fetch &bc = n->bc;
  468.         const fetch_op_info *fop = bc.op_ptr;
  469.  
  470.         assert(!(fop->flags & FF_VTX));
  471.  
  472.         if (ctx.is_r600())
  473.                 bb << TEX_WORD0_R6()
  474.                                 .BC_FRAC_MODE(bc.bc_frac_mode)
  475.                                 .FETCH_WHOLE_QUAD(bc.fetch_whole_quad)
  476.                                 .RESOURCE_ID(bc.resource_id)
  477.                                 .SRC_GPR(bc.src_gpr)
  478.                                 .SRC_REL(bc.src_rel)
  479.                                 .TEX_INST(ctx.fetch_opcode(bc.op));
  480.  
  481.         else if (ctx.is_r700())
  482.                 bb << TEX_WORD0_R7()
  483.                                 .ALT_CONST(bc.alt_const)
  484.                                 .BC_FRAC_MODE(bc.bc_frac_mode)
  485.                                 .FETCH_WHOLE_QUAD(bc.fetch_whole_quad)
  486.                                 .RESOURCE_ID(bc.resource_id)
  487.                                 .SRC_GPR(bc.src_gpr)
  488.                                 .SRC_REL(bc.src_rel)
  489.                                 .TEX_INST(ctx.fetch_opcode(bc.op));
  490.  
  491.         else
  492.                 bb << TEX_WORD0_EGCM()
  493.                                 .ALT_CONST(bc.alt_const)
  494.                                 .FETCH_WHOLE_QUAD(bc.fetch_whole_quad)
  495.                                 .INST_MOD(bc.inst_mod)
  496.                                 .RESOURCE_ID(bc.resource_id)
  497.                                 .RESOURCE_INDEX_MODE(bc.resource_index_mode)
  498.                                 .SAMPLER_INDEX_MODE(bc.sampler_index_mode)
  499.                                 .SRC_GPR(bc.src_gpr)
  500.                                 .SRC_REL(bc.src_rel)
  501.                                 .TEX_INST(ctx.fetch_opcode(bc.op));
  502.  
  503.         bb << TEX_WORD1_ALL()
  504.                         .COORD_TYPE_X(bc.coord_type[0])
  505.                         .COORD_TYPE_Y(bc.coord_type[1])
  506.                         .COORD_TYPE_Z(bc.coord_type[2])
  507.                         .COORD_TYPE_W(bc.coord_type[3])
  508.                         .DST_GPR(bc.dst_gpr)
  509.                         .DST_REL(bc.dst_rel)
  510.                         .DST_SEL_X(bc.dst_sel[0])
  511.                         .DST_SEL_Y(bc.dst_sel[1])
  512.                         .DST_SEL_Z(bc.dst_sel[2])
  513.                         .DST_SEL_W(bc.dst_sel[3])
  514.                         .LOD_BIAS(bc.lod_bias);
  515.  
  516.         bb << TEX_WORD2_ALL()
  517.                         .OFFSET_X(bc.offset[0])
  518.                         .OFFSET_Y(bc.offset[1])
  519.                         .OFFSET_Z(bc.offset[2])
  520.                         .SAMPLER_ID(bc.sampler_id)
  521.                         .SRC_SEL_X(bc.src_sel[0])
  522.                         .SRC_SEL_Y(bc.src_sel[1])
  523.                         .SRC_SEL_Z(bc.src_sel[2])
  524.                         .SRC_SEL_W(bc.src_sel[3]);
  525.  
  526.         bb << 0;
  527.         return 0;
  528. }
  529.  
  530. int bc_builder::build_fetch_vtx(fetch_node* n) {
  531.         const bc_fetch &bc = n->bc;
  532.         const fetch_op_info *fop = bc.op_ptr;
  533.  
  534.         assert(fop->flags & FF_VTX);
  535.  
  536.         if (!ctx.is_cayman())
  537.                 bb << VTX_WORD0_R6R7EG()
  538.                                 .BUFFER_ID(bc.resource_id)
  539.                                 .FETCH_TYPE(bc.fetch_type)
  540.                                 .FETCH_WHOLE_QUAD(bc.fetch_whole_quad)
  541.                                 .MEGA_FETCH_COUNT(bc.mega_fetch_count)
  542.                                 .SRC_GPR(bc.src_gpr)
  543.                                 .SRC_REL(bc.src_rel)
  544.                                 .SRC_SEL_X(bc.src_sel[0])
  545.                                 .VC_INST(ctx.fetch_opcode(bc.op));
  546.  
  547.         else
  548.                 bb << VTX_WORD0_CM()
  549.                                 .BUFFER_ID(bc.resource_id)
  550.                                 .COALESCED_READ(bc.coalesced_read)
  551.                                 .FETCH_TYPE(bc.fetch_type)
  552.                                 .FETCH_WHOLE_QUAD(bc.fetch_whole_quad)
  553.                                 .LDS_REQ(bc.lds_req)
  554.                                 .SRC_GPR(bc.src_gpr)
  555.                                 .SRC_REL(bc.src_rel)
  556.                                 .SRC_SEL_X(bc.src_sel[0])
  557.                                 .SRC_SEL_Y(bc.src_sel[1])
  558.                                 .STRUCTURED_READ(bc.structured_read)
  559.                                 .VC_INST(ctx.fetch_opcode(bc.op));
  560.  
  561.         if (bc.op == FETCH_OP_SEMFETCH)
  562.                 bb << VTX_WORD1_SEM_ALL()
  563.                                 .DATA_FORMAT(bc.data_format)
  564.                                 .DST_SEL_X(bc.dst_sel[0])
  565.                                 .DST_SEL_Y(bc.dst_sel[1])
  566.                                 .DST_SEL_Z(bc.dst_sel[2])
  567.                                 .DST_SEL_W(bc.dst_sel[3])
  568.                                 .FORMAT_COMP_ALL(bc.format_comp_all)
  569.                                 .NUM_FORMAT_ALL(bc.num_format_all)
  570.                                 .SEMANTIC_ID(bc.semantic_id)
  571.                                 .SRF_MODE_ALL(bc.srf_mode_all)
  572.                                 .USE_CONST_FIELDS(bc.use_const_fields);
  573.         else
  574.                 bb << VTX_WORD1_GPR_ALL()
  575.                                 .DATA_FORMAT(bc.data_format)
  576.                                 .DST_GPR(bc.dst_gpr)
  577.                                 .DST_REL(bc.dst_rel)
  578.                                 .DST_SEL_X(bc.dst_sel[0])
  579.                                 .DST_SEL_Y(bc.dst_sel[1])
  580.                                 .DST_SEL_Z(bc.dst_sel[2])
  581.                                 .DST_SEL_W(bc.dst_sel[3])
  582.                                 .FORMAT_COMP_ALL(bc.format_comp_all)
  583.                                 .NUM_FORMAT_ALL(bc.num_format_all)
  584.                                 .SRF_MODE_ALL(bc.srf_mode_all)
  585.                                 .USE_CONST_FIELDS(bc.use_const_fields);
  586.  
  587.         switch (ctx.hw_class) {
  588.         case HW_CLASS_R600:
  589.                 bb << VTX_WORD2_R6()
  590.                                 .CONST_BUF_NO_STRIDE(bc.const_buf_no_stride)
  591.                                 .ENDIAN_SWAP(bc.endian_swap)
  592.                                 .MEGA_FETCH(bc.mega_fetch)
  593.                                 .OFFSET(bc.offset[0]);
  594.                 break;
  595.         case HW_CLASS_R700:
  596.                 bb << VTX_WORD2_R7()
  597.                                 .ALT_CONST(bc.alt_const)
  598.                                 .CONST_BUF_NO_STRIDE(bc.const_buf_no_stride)
  599.                                 .ENDIAN_SWAP(bc.endian_swap)
  600.                                 .MEGA_FETCH(bc.mega_fetch)
  601.                                 .OFFSET(bc.offset[0]);
  602.                 break;
  603.         case HW_CLASS_EVERGREEN:
  604.                 bb << VTX_WORD2_EG()
  605.                                 .ALT_CONST(bc.alt_const)
  606.                                 .BUFFER_INDEX_MODE(bc.resource_index_mode)
  607.                                 .CONST_BUF_NO_STRIDE(bc.const_buf_no_stride)
  608.                                 .ENDIAN_SWAP(bc.endian_swap)
  609.                                 .MEGA_FETCH(bc.mega_fetch)
  610.                                 .OFFSET(bc.offset[0]);
  611.                 break;
  612.         case HW_CLASS_CAYMAN:
  613.                 bb << VTX_WORD2_CM()
  614.                                 .ALT_CONST(bc.alt_const)
  615.                                 .BUFFER_INDEX_MODE(bc.resource_index_mode)
  616.                                 .CONST_BUF_NO_STRIDE(bc.const_buf_no_stride)
  617.                                 .ENDIAN_SWAP(bc.endian_swap)
  618.                                 .OFFSET(bc.offset[0]);
  619.                 break;
  620.         default:
  621.                 assert(!"unknown hw class");
  622.                 return -1;
  623.         }
  624.  
  625.         bb << 0;
  626.         return 0;
  627. }
  628.  
  629. }
  630.