Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
  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. #include "r600_pipe.h"
  24. #include "r600_opcodes.h"
  25. #include "r600_shader.h"
  26.  
  27. #include "util/u_memory.h"
  28. #include "eg_sq.h"
  29. #include <errno.h>
  30.  
  31. int eg_bytecode_cf_build(struct r600_bytecode *bc, struct r600_bytecode_cf *cf)
  32. {
  33.         unsigned id = cf->id;
  34.  
  35.         if (cf->op == CF_NATIVE) {
  36.                 bc->bytecode[id++] = cf->isa[0];
  37.                 bc->bytecode[id++] = cf->isa[1];
  38.         } else {
  39.                 const struct cf_op_info *cfop = r600_isa_cf(cf->op);
  40.                 unsigned opcode = r600_isa_cf_opcode(bc->isa->hw_class, cf->op);
  41.                 if (cfop->flags & CF_ALU) { /* ALU clauses */
  42.  
  43.                         /* prepend ALU_EXTENDED if we need more than 2 kcache sets */
  44.                         if (cf->eg_alu_extended) {
  45.                                 bc->bytecode[id++] =
  46.                                                 S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE0(cf->kcache[0].index_mode) |
  47.                                                 S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE1(cf->kcache[1].index_mode) |
  48.                                                 S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE2(cf->kcache[2].index_mode) |
  49.                                                 S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE3(cf->kcache[3].index_mode) |
  50.                                                 S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK2(cf->kcache[2].bank) |
  51.                                                 S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK3(cf->kcache[3].bank) |
  52.                                                 S_SQ_CF_ALU_WORD0_EXT_KCACHE_MODE2(cf->kcache[2].mode);
  53.                                 bc->bytecode[id++] =
  54.                                                 S_SQ_CF_ALU_WORD1_EXT_CF_INST(
  55.                                                         r600_isa_cf_opcode(bc->isa->hw_class, CF_OP_ALU_EXT)) |
  56.                                                 S_SQ_CF_ALU_WORD1_EXT_KCACHE_MODE3(cf->kcache[3].mode) |
  57.                                                 S_SQ_CF_ALU_WORD1_EXT_KCACHE_ADDR2(cf->kcache[2].addr) |
  58.                                                 S_SQ_CF_ALU_WORD1_EXT_KCACHE_ADDR3(cf->kcache[3].addr) |
  59.                                                 S_SQ_CF_ALU_WORD1_EXT_BARRIER(1);
  60.                         }
  61.                         bc->bytecode[id++] = S_SQ_CF_ALU_WORD0_ADDR(cf->addr >> 1) |
  62.                                         S_SQ_CF_ALU_WORD0_KCACHE_MODE0(cf->kcache[0].mode) |
  63.                                         S_SQ_CF_ALU_WORD0_KCACHE_BANK0(cf->kcache[0].bank) |
  64.                                         S_SQ_CF_ALU_WORD0_KCACHE_BANK1(cf->kcache[1].bank);
  65.                         bc->bytecode[id++] = S_SQ_CF_ALU_WORD1_CF_INST(opcode) |
  66.                                         S_SQ_CF_ALU_WORD1_KCACHE_MODE1(cf->kcache[1].mode) |
  67.                                         S_SQ_CF_ALU_WORD1_KCACHE_ADDR0(cf->kcache[0].addr) |
  68.                                         S_SQ_CF_ALU_WORD1_KCACHE_ADDR1(cf->kcache[1].addr) |
  69.                                         S_SQ_CF_ALU_WORD1_BARRIER(1) |
  70.                                         S_SQ_CF_ALU_WORD1_COUNT((cf->ndw / 2) - 1);
  71.                 } else if (cfop->flags & CF_CLAUSE) {
  72.                         /* CF_TEX/VTX (CF_ALU already handled above) */
  73.                         bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->addr >> 1);
  74.                         bc->bytecode[id++] = S_SQ_CF_WORD1_CF_INST(opcode) |
  75.                                         S_SQ_CF_WORD1_BARRIER(1) |
  76.                                         S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1);
  77.                 } else if (cfop->flags & CF_EXP) {
  78.                         /* EXPORT instructions */
  79.                         bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(cf->output.gpr) |
  80.                                         S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(cf->output.elem_size) |
  81.                                         S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(cf->output.array_base) |
  82.                                         S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(cf->output.type) |
  83.                                         S_SQ_CF_ALLOC_EXPORT_WORD0_INDEX_GPR(cf->output.index_gpr);
  84.                         bc->bytecode[id] =
  85.                                         S_SQ_CF_ALLOC_EXPORT_WORD1_BURST_COUNT(cf->output.burst_count - 1) |
  86.                                         S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X(cf->output.swizzle_x) |
  87.                                         S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(cf->output.swizzle_y) |
  88.                                         S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(cf->output.swizzle_z) |
  89.                                         S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(cf->output.swizzle_w) |
  90.                                         S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(cf->barrier) |
  91.                                         S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(opcode);
  92.  
  93.                         if (bc->chip_class == EVERGREEN) /* no EOP on cayman */
  94.                                 bc->bytecode[id] |= S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->end_of_program);
  95.                         id++;
  96.                 } else if (cfop->flags & CF_MEM) {
  97.                         /* MEM_STREAM, MEM_RING instructions */
  98.                         bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(cf->output.gpr) |
  99.                                         S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(cf->output.elem_size) |
  100.                                         S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(cf->output.array_base) |
  101.                                         S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(cf->output.type) |
  102.                                         S_SQ_CF_ALLOC_EXPORT_WORD0_INDEX_GPR(cf->output.index_gpr);
  103.                         bc->bytecode[id] = S_SQ_CF_ALLOC_EXPORT_WORD1_BURST_COUNT(cf->output.burst_count - 1) |
  104.                                         S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(cf->barrier) |
  105.                                         S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(opcode) |
  106.                                         S_SQ_CF_ALLOC_EXPORT_WORD1_BUF_COMP_MASK(cf->output.comp_mask) |
  107.                                         S_SQ_CF_ALLOC_EXPORT_WORD1_BUF_ARRAY_SIZE(cf->output.array_size);
  108.                         if (bc->chip_class == EVERGREEN) /* no EOP on cayman */
  109.                                 bc->bytecode[id] |= S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->end_of_program);
  110.                         id++;
  111.                 } else {
  112.                         /* other instructions */
  113.                         bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->cf_addr >> 1);
  114.                         bc->bytecode[id++] =  S_SQ_CF_WORD1_CF_INST(opcode)|
  115.                                         S_SQ_CF_WORD1_BARRIER(1) |
  116.                                         S_SQ_CF_WORD1_COND(cf->cond) |
  117.                                         S_SQ_CF_WORD1_POP_COUNT(cf->pop_count) |
  118.                                         S_SQ_CF_WORD1_END_OF_PROGRAM(cf->end_of_program);
  119.                 }
  120.         }
  121.         return 0;
  122. }
  123.  
  124. #if 0
  125. void eg_bytecode_export_read(struct r600_bytecode *bc,
  126.                 struct r600_bytecode_output *output, uint32_t word0, uint32_t word1)
  127. {
  128.         output->array_base = G_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(word0);
  129.         output->type = G_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(word0);
  130.         output->gpr = G_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(word0);
  131.         output->elem_size = G_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(word0);
  132.  
  133.         output->swizzle_x = G_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X(word1);
  134.         output->swizzle_y = G_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(word1);
  135.         output->swizzle_z = G_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(word1);
  136.         output->swizzle_w = G_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(word1);
  137.         output->burst_count = G_SQ_CF_ALLOC_EXPORT_WORD1_BURST_COUNT(word1);
  138.         output->end_of_program = G_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(word1);
  139.         output->op = r600_isa_cf_by_opcode(bc->isa,
  140.                         G_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(word1), /* is_cf_alu = */ 0 );
  141.         output->barrier = G_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(word1);
  142.         output->array_size = G_SQ_CF_ALLOC_EXPORT_WORD1_BUF_ARRAY_SIZE(word1);
  143.         output->comp_mask = G_SQ_CF_ALLOC_EXPORT_WORD1_BUF_COMP_MASK(word1);
  144. }
  145. #endif
  146.  
  147. int egcm_load_index_reg(struct r600_bytecode *bc, unsigned id, bool inside_alu_clause)
  148. {
  149.         struct r600_bytecode_alu alu;
  150.         int r;
  151.         unsigned type;
  152.  
  153.         assert(id < 2);
  154.         assert(bc->chip_class >= EVERGREEN);
  155.  
  156.         if (bc->index_loaded[id])
  157.                 return 0;
  158.  
  159.         memset(&alu, 0, sizeof(alu));
  160.         alu.op = ALU_OP1_MOVA_INT;
  161.         alu.src[0].sel = bc->index_reg[id];
  162.         alu.src[0].chan = 0;
  163.         alu.last = 1;
  164.         r = r600_bytecode_add_alu(bc, &alu);
  165.         if (r)
  166.                 return r;
  167.  
  168.         bc->ar_loaded = 0; /* clobbered */
  169.  
  170.         memset(&alu, 0, sizeof(alu));
  171.         alu.op = id == 0 ? ALU_OP0_SET_CF_IDX0 : ALU_OP0_SET_CF_IDX1;
  172.         alu.last = 1;
  173.         r = r600_bytecode_add_alu(bc, &alu);
  174.         if (r)
  175.                 return r;
  176.  
  177.         /* Must split ALU group as index only applies to following group */
  178.         if (inside_alu_clause) {
  179.                 type = bc->cf_last->op;
  180.                 if ((r = r600_bytecode_add_cf(bc))) {
  181.                         return r;
  182.                 }
  183.                 bc->cf_last->op = type;
  184.         }
  185.  
  186.         bc->index_loaded[id] = 1;
  187.  
  188.         return 0;
  189. }
  190.