r600g: use tables with ISA info v3

v3: added some flags including condition codes for ALU,
    fixed issue with CF reverse lookup (overlapping ranges of CF_ALU_xxx
    and other CF instructions)
    rebased on current master

Signed-off-by: Vadim Girlin <vadimgirlin@gmail.com>
This commit is contained in:
Vadim Girlin 2013-02-01 11:45:35 +04:00
parent b68a3b865b
commit 022122ee63
10 changed files with 2377 additions and 1788 deletions

View file

@ -3,6 +3,7 @@ C_SOURCES = \
r600_blit.c \
r600_buffer.c \
r600_hw_context.c \
r600_isa.c \
r600_pipe.c \
r600_query.c \
r600_resource.c \

View file

@ -32,121 +32,94 @@ int eg_bytecode_cf_build(struct r600_bytecode *bc, struct r600_bytecode_cf *cf)
{
unsigned id = cf->id;
switch (cf->inst) {
case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU:
case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER:
case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER:
case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE:
/* prepend ALU_EXTENDED if we need more than 2 kcache sets */
if (cf->eg_alu_extended) {
bc->bytecode[id++] =
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE0(V_SQ_CF_INDEX_NONE) |
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE1(V_SQ_CF_INDEX_NONE) |
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE2(V_SQ_CF_INDEX_NONE) |
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE3(V_SQ_CF_INDEX_NONE) |
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK2(cf->kcache[2].bank) |
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK3(cf->kcache[3].bank) |
S_SQ_CF_ALU_WORD0_EXT_KCACHE_MODE2(cf->kcache[2].mode);
bc->bytecode[id++] = EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_EXTENDED |
S_SQ_CF_ALU_WORD1_EXT_KCACHE_MODE3(cf->kcache[3].mode) |
S_SQ_CF_ALU_WORD1_EXT_KCACHE_ADDR2(cf->kcache[2].addr) |
S_SQ_CF_ALU_WORD1_EXT_KCACHE_ADDR3(cf->kcache[3].addr) |
S_SQ_CF_ALU_WORD1_EXT_BARRIER(1);
}
if (cf->op == CF_NATIVE) {
bc->bytecode[id++] = cf->isa[0];
bc->bytecode[id++] = cf->isa[1];
} else {
const struct cf_op_info *cfop = r600_isa_cf(cf->op);
unsigned opcode = r600_isa_cf_opcode(bc->isa->hw_class, cf->op);
if (cfop->flags & CF_ALU) { /* ALU clauses */
bc->bytecode[id++] = S_SQ_CF_ALU_WORD0_ADDR(cf->addr >> 1) |
S_SQ_CF_ALU_WORD0_KCACHE_MODE0(cf->kcache[0].mode) |
S_SQ_CF_ALU_WORD0_KCACHE_BANK0(cf->kcache[0].bank) |
S_SQ_CF_ALU_WORD0_KCACHE_BANK1(cf->kcache[1].bank);
bc->bytecode[id++] = cf->inst |
S_SQ_CF_ALU_WORD1_KCACHE_MODE1(cf->kcache[1].mode) |
S_SQ_CF_ALU_WORD1_KCACHE_ADDR0(cf->kcache[0].addr) |
S_SQ_CF_ALU_WORD1_KCACHE_ADDR1(cf->kcache[1].addr) |
/* prepend ALU_EXTENDED if we need more than 2 kcache sets */
if (cf->eg_alu_extended) {
bc->bytecode[id++] =
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE0(V_SQ_CF_INDEX_NONE) |
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE1(V_SQ_CF_INDEX_NONE) |
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE2(V_SQ_CF_INDEX_NONE) |
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE3(V_SQ_CF_INDEX_NONE) |
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK2(cf->kcache[2].bank) |
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK3(cf->kcache[3].bank) |
S_SQ_CF_ALU_WORD0_EXT_KCACHE_MODE2(cf->kcache[2].mode);
bc->bytecode[id++] =
S_SQ_CF_ALU_WORD1_EXT_CF_INST(
r600_isa_cf_opcode(bc->isa->hw_class, CF_OP_ALU_EXT)) |
S_SQ_CF_ALU_WORD1_EXT_KCACHE_MODE3(cf->kcache[3].mode) |
S_SQ_CF_ALU_WORD1_EXT_KCACHE_ADDR2(cf->kcache[2].addr) |
S_SQ_CF_ALU_WORD1_EXT_KCACHE_ADDR3(cf->kcache[3].addr) |
S_SQ_CF_ALU_WORD1_EXT_BARRIER(1);
}
bc->bytecode[id++] = S_SQ_CF_ALU_WORD0_ADDR(cf->addr >> 1) |
S_SQ_CF_ALU_WORD0_KCACHE_MODE0(cf->kcache[0].mode) |
S_SQ_CF_ALU_WORD0_KCACHE_BANK0(cf->kcache[0].bank) |
S_SQ_CF_ALU_WORD0_KCACHE_BANK1(cf->kcache[1].bank);
bc->bytecode[id++] = S_SQ_CF_ALU_WORD1_CF_INST(opcode) |
S_SQ_CF_ALU_WORD1_KCACHE_MODE1(cf->kcache[1].mode) |
S_SQ_CF_ALU_WORD1_KCACHE_ADDR0(cf->kcache[0].addr) |
S_SQ_CF_ALU_WORD1_KCACHE_ADDR1(cf->kcache[1].addr) |
S_SQ_CF_ALU_WORD1_BARRIER(1) |
S_SQ_CF_ALU_WORD1_COUNT((cf->ndw / 2) - 1);
break;
case EG_V_SQ_CF_WORD1_SQ_CF_INST_TEX:
case EG_V_SQ_CF_WORD1_SQ_CF_INST_VTX:
bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->addr >> 1);
bc->bytecode[id++] = cf->inst |
} else if (cfop->flags & CF_CLAUSE) {
/* CF_TEX/VTX (CF_ALU already handled above) */
bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->addr >> 1);
bc->bytecode[id++] = S_SQ_CF_WORD1_CF_INST(opcode) |
S_SQ_CF_WORD1_BARRIER(1) |
S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1);
break;
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(cf->output.gpr) |
S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(cf->output.elem_size) |
S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(cf->output.array_base) |
S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(cf->output.type);
bc->bytecode[id] = S_SQ_CF_ALLOC_EXPORT_WORD1_BURST_COUNT(cf->output.burst_count - 1) |
S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X(cf->output.swizzle_x) |
S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(cf->output.swizzle_y) |
S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(cf->output.swizzle_z) |
S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(cf->output.swizzle_w) |
S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(cf->output.barrier) |
cf->output.inst;
if (bc->chip_class == EVERGREEN) /* no EOP on cayman */
bc->bytecode[id] |= S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->output.end_of_program);
id++;
break;
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM0_BUF0:
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM0_BUF1:
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM0_BUF2:
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM0_BUF3:
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM1_BUF0:
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM1_BUF1:
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM1_BUF2:
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM1_BUF3:
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM2_BUF0:
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM2_BUF1:
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM2_BUF2:
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM2_BUF3:
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM3_BUF0:
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM3_BUF1:
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM3_BUF2:
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM3_BUF3:
bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(cf->output.gpr) |
S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(cf->output.elem_size) |
S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(cf->output.array_base) |
S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(cf->output.type);
bc->bytecode[id] = S_SQ_CF_ALLOC_EXPORT_WORD1_BURST_COUNT(cf->output.burst_count - 1) |
S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(cf->output.barrier) |
cf->output.inst |
S_SQ_CF_ALLOC_EXPORT_WORD1_BUF_COMP_MASK(cf->output.comp_mask) |
S_SQ_CF_ALLOC_EXPORT_WORD1_BUF_ARRAY_SIZE(cf->output.array_size);
if (bc->chip_class == EVERGREEN) /* no EOP on cayman */
bc->bytecode[id] |= S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->output.end_of_program);
id++;
break;
case EG_V_SQ_CF_WORD1_SQ_CF_INST_JUMP:
case EG_V_SQ_CF_WORD1_SQ_CF_INST_ELSE:
case EG_V_SQ_CF_WORD1_SQ_CF_INST_POP:
case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL:
case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_DX10:
case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END:
case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE:
case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK:
case EG_V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS:
case EG_V_SQ_CF_WORD1_SQ_CF_INST_RETURN:
case CM_V_SQ_CF_WORD1_SQ_CF_INST_END:
bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->cf_addr >> 1);
bc->bytecode[id++] = cf->inst |
} else if (cfop->flags & CF_EXP) {
/* EXPORT instructions */
bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(cf->output.gpr) |
S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(cf->output.elem_size) |
S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(cf->output.array_base) |
S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(cf->output.type);
bc->bytecode[id] =
S_SQ_CF_ALLOC_EXPORT_WORD1_BURST_COUNT(cf->output.burst_count - 1) |
S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X(cf->output.swizzle_x) |
S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(cf->output.swizzle_y) |
S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(cf->output.swizzle_z) |
S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(cf->output.swizzle_w) |
S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(cf->output.barrier) |
S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(opcode);
if (bc->chip_class == EVERGREEN) /* no EOP on cayman */
bc->bytecode[id] |= S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->output.end_of_program);
id++;
} else if (cfop->flags & CF_STRM) {
/* MEM_STREAM instructions */
bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(cf->output.gpr) |
S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(cf->output.elem_size) |
S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(cf->output.array_base) |
S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(cf->output.type);
bc->bytecode[id] = S_SQ_CF_ALLOC_EXPORT_WORD1_BURST_COUNT(cf->output.burst_count - 1) |
S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(cf->output.barrier) |
S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(opcode) |
S_SQ_CF_ALLOC_EXPORT_WORD1_BUF_COMP_MASK(cf->output.comp_mask) |
S_SQ_CF_ALLOC_EXPORT_WORD1_BUF_ARRAY_SIZE(cf->output.array_size);
if (bc->chip_class == EVERGREEN) /* no EOP on cayman */
bc->bytecode[id] |= S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->output.end_of_program);
id++;
} else {
/* branch, loop, call, return instructions */
bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->cf_addr >> 1);
bc->bytecode[id++] = S_SQ_CF_WORD1_CF_INST(opcode)|
S_SQ_CF_WORD1_BARRIER(1) |
S_SQ_CF_WORD1_COND(cf->cond) |
S_SQ_CF_WORD1_POP_COUNT(cf->pop_count);
break;
case CF_NATIVE:
bc->bytecode[id++] = cf->isa[0];
bc->bytecode[id++] = cf->isa[1];
break;
default:
R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst);
return -EINVAL;
}
}
return 0;
}
void eg_bytecode_export_read(struct r600_bytecode_output *output, uint32_t word0, uint32_t word1)
void eg_bytecode_export_read(struct r600_bytecode *bc,
struct r600_bytecode_output *output, uint32_t word0, uint32_t word1)
{
output->array_base = G_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(word0);
output->type = G_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(word0);
@ -159,7 +132,8 @@ void eg_bytecode_export_read(struct r600_bytecode_output *output, uint32_t word0
output->swizzle_w = G_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(word1);
output->burst_count = G_SQ_CF_ALLOC_EXPORT_WORD1_BURST_COUNT(word1);
output->end_of_program = G_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(word1);
output->inst = EG_S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(G_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(word1));
output->op = r600_isa_cf_by_opcode(bc->isa,
G_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(word1), /* is_cf_alu = */ 0 );
output->barrier = G_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(word1);
output->array_size = G_SQ_CF_ALLOC_EXPORT_WORD1_BUF_ARRAY_SIZE(word1);
output->comp_mask = G_SQ_CF_ALLOC_EXPORT_WORD1_BUF_COMP_MASK(word1);

File diff suppressed because it is too large Load diff

View file

@ -24,6 +24,7 @@
#define R600_ASM_H
#include "r600_pipe.h"
#include "r600_isa.h"
struct r600_bytecode_alu_src {
unsigned sel;
@ -47,7 +48,7 @@ struct r600_bytecode_alu {
struct list_head list;
struct r600_bytecode_alu_src src[3];
struct r600_bytecode_alu_dst dst;
unsigned inst;
unsigned op;
unsigned last;
unsigned is_op3;
unsigned execute_mask;
@ -61,7 +62,7 @@ struct r600_bytecode_alu {
struct r600_bytecode_tex {
struct list_head list;
unsigned inst;
unsigned op;
unsigned inst_mod;
unsigned resource_id;
unsigned src_gpr;
@ -89,7 +90,7 @@ struct r600_bytecode_tex {
struct r600_bytecode_vtx {
struct list_head list;
unsigned inst;
unsigned op;
unsigned fetch_type;
unsigned buffer_id;
unsigned src_gpr;
@ -116,8 +117,7 @@ struct r600_bytecode_output {
unsigned type;
unsigned end_of_program;
/* CF_INST. This is already bit-shifted and only needs to be or'd for bytecode. */
unsigned inst;
unsigned op;
unsigned elem_size;
unsigned gpr;
@ -135,20 +135,10 @@ struct r600_bytecode_kcache {
unsigned addr;
};
/* A value of CF_NATIVE in r600_bytecode_cf::inst means that this instruction
* has already been encoded, and the encoding has been stored in
* r600_bytecode::isa. This is used by the LLVM backend to emit CF instructions
* e.g. RAT_WRITE_* that can't be properly represented by struct
* r600_bytecode_cf.
*/
#define CF_NATIVE ~0
struct r600_bytecode_cf {
struct list_head list;
/* CF_INST. This is already bit-shifted and only needs to be or'd for bytecode. */
unsigned inst;
unsigned op;
unsigned addr;
unsigned ndw;
unsigned id;
@ -216,6 +206,7 @@ struct r600_bytecode {
unsigned ar_chan;
unsigned ar_handling;
unsigned r6xx_nop_after_rel_dst;
struct r600_isa* isa;
};
/* eg_asm.c */
@ -227,16 +218,24 @@ void r600_bytecode_init(struct r600_bytecode *bc,
enum radeon_family family,
enum r600_msaa_texture_mode msaa_texture_mode);
void r600_bytecode_clear(struct r600_bytecode *bc);
int r600_bytecode_add_alu(struct r600_bytecode *bc, const struct r600_bytecode_alu *alu);
int r600_bytecode_add_vtx(struct r600_bytecode *bc, const struct r600_bytecode_vtx *vtx);
int r600_bytecode_add_tex(struct r600_bytecode *bc, const struct r600_bytecode_tex *tex);
int r600_bytecode_add_output(struct r600_bytecode *bc, const struct r600_bytecode_output *output);
int r600_bytecode_add_alu(struct r600_bytecode *bc,
const struct r600_bytecode_alu *alu);
int r600_bytecode_add_vtx(struct r600_bytecode *bc,
const struct r600_bytecode_vtx *vtx);
int r600_bytecode_add_tex(struct r600_bytecode *bc,
const struct r600_bytecode_tex *tex);
int r600_bytecode_add_output(struct r600_bytecode *bc,
const struct r600_bytecode_output *output);
int r600_bytecode_build(struct r600_bytecode *bc);
int r600_bytecode_add_cfinst(struct r600_bytecode *bc, int inst);
int r600_bytecode_add_alu_type(struct r600_bytecode *bc, const struct r600_bytecode_alu *alu, int type);
void r600_bytecode_special_constants(uint32_t value, unsigned *sel, unsigned *neg);
int r600_bytecode_add_cfinst(struct r600_bytecode *bc,
unsigned op);
int r600_bytecode_add_alu_type(struct r600_bytecode *bc,
const struct r600_bytecode_alu *alu, unsigned type);
void r600_bytecode_special_constants(uint32_t value,
unsigned *sel, unsigned *neg);
void r600_bytecode_dump(struct r600_bytecode *bc);
void r600_bytecode_alu_read(struct r600_bytecode_alu *alu, uint32_t word0, uint32_t word1);
void r600_bytecode_alu_read(struct r600_bytecode *bc,
struct r600_bytecode_alu *alu, uint32_t word0, uint32_t word1);
int cm_bytecode_add_cf_end(struct r600_bytecode *bc);
@ -245,11 +244,16 @@ void *r600_create_vertex_fetch_shader(struct pipe_context *ctx,
const struct pipe_vertex_element *elements);
/* r700_asm.c */
void r700_bytecode_cf_vtx_build(uint32_t *bytecode, const struct r600_bytecode_cf *cf);
int r700_bytecode_alu_build(struct r600_bytecode *bc, struct r600_bytecode_alu *alu, unsigned id);
void r700_bytecode_alu_read(struct r600_bytecode_alu *alu, uint32_t word0, uint32_t word1);
void r600_bytecode_export_read(struct r600_bytecode_output *output, uint32_t word0, uint32_t word1);
void eg_bytecode_export_read(struct r600_bytecode_output *output, uint32_t word0, uint32_t word1);
void r700_bytecode_cf_vtx_build(uint32_t *bytecode,
const struct r600_bytecode_cf *cf);
int r700_bytecode_alu_build(struct r600_bytecode *bc,
struct r600_bytecode_alu *alu, unsigned id);
void r700_bytecode_alu_read(struct r600_bytecode *bc,
struct r600_bytecode_alu *alu, uint32_t word0, uint32_t word1);
void r600_bytecode_export_read(struct r600_bytecode *bc,
struct r600_bytecode_output *output, uint32_t word0, uint32_t word1);
void eg_bytecode_export_read(struct r600_bytecode *bc,
struct r600_bytecode_output *output, uint32_t word0, uint32_t word1);
void r600_vertex_data_type(enum pipe_format pformat, unsigned *format,
unsigned *num_format, unsigned *format_comp, unsigned *endian);

View file

@ -0,0 +1,116 @@
/*
* Copyright 2012 Vadim Girlin <vadimgirlin@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Vadim Girlin
*/
#include "r600_pipe.h"
#include "r600_isa.h"
int r600_isa_init(struct r600_context *ctx, struct r600_isa *isa) {
assert(ctx->chip_class >= R600 && ctx->chip_class <= CAYMAN);
isa->hw_class = ctx->chip_class - R600;
assert(isa->hw_class >= ISA_CC_R600 && isa->hw_class <= ISA_CC_EVERGREEN);
/* reverse lookup maps are required for bytecode parsing only,
* currently it's needed for handling the bytestream from llvm backend */
#if defined R600_USE_LLVM || defined HAVE_OPENCL
unsigned i, use_llvm;
use_llvm = debug_get_bool_option("R600_LLVM", TRUE);
if (!use_llvm)
return 0;
isa->alu_op2_map = calloc(256, sizeof(unsigned));
if (!isa->alu_op2_map)
return -1;
isa->alu_op3_map = calloc(256, sizeof(unsigned));
if (!isa->alu_op3_map)
return -1;
isa->fetch_map = calloc(256, sizeof(unsigned));
if (!isa->fetch_map)
return -1;
isa->cf_map = calloc(256, sizeof(unsigned));
if (!isa->cf_map)
return -1;
for (i = 0; i < TABLE_SIZE(alu_op_table); ++i) {
const struct alu_op_info *op = &alu_op_table[i];
unsigned opc;
if (op->flags & AF_LDS || op->slots[isa->hw_class] == 0)
continue;
opc = op->opcode[isa->hw_class >> 1];
assert(opc != -1);
if (op->src_count == 3)
isa->alu_op3_map[opc] = i + 1;
else
isa->alu_op2_map[opc] = i + 1;
}
for (i = 0; i < TABLE_SIZE(fetch_op_table); ++i) {
const struct fetch_op_info *op = &fetch_op_table[i];
unsigned opc = op->opcode[isa->hw_class];
if ((op->flags & FF_GDS) || ((opc & 0xFF) != opc))
continue; /* ignore GDS ops and INST_MOD versions for now */
isa->fetch_map[opc] = i + 1;
}
for (i = 0; i < TABLE_SIZE(cf_op_table); ++i) {
const struct cf_op_info *op = &cf_op_table[i];
unsigned opc = op->opcode[isa->hw_class];
if (opc == -1)
continue;
/* using offset for CF_ALU_xxx opcodes because they overlap with other
* CF opcodes (they use different encoding in hw) */
if (op->flags & CF_ALU)
opc += 0x80;
isa->cf_map[opc] = i + 1;
}
#endif
return 0;
}
int r600_isa_destroy(struct r600_isa *isa) {
if (!isa)
return 0;
if (isa->alu_op2_map)
free(isa->alu_op2_map);
if (isa->alu_op3_map)
free(isa->alu_op3_map);
if (isa->fetch_map)
free(isa->fetch_map);
if (isa->cf_map)
free(isa->cf_map);
free(isa);
return 0;
}

File diff suppressed because it is too large Load diff

View file

@ -22,6 +22,7 @@
*/
#include "r600_pipe.h"
#include "r600_public.h"
#include "r600_isa.h"
#include <errno.h>
#include "pipe/p_shader_tokens.h"
@ -260,6 +261,8 @@ static void r600_destroy_context(struct pipe_context *context)
{
struct r600_context *rctx = (struct r600_context *)context;
r600_isa_destroy(rctx->isa);
pipe_resource_reference((struct pipe_resource**)&rctx->dummy_cmask, NULL);
pipe_resource_reference((struct pipe_resource**)&rctx->dummy_fmask, NULL);
@ -419,7 +422,11 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
rctx->allocator_so_filled_size = u_suballocator_create(&rctx->context, 4096, 4,
0, PIPE_USAGE_STATIC, TRUE);
if (!rctx->allocator_so_filled_size)
if (!rctx->allocator_so_filled_size)
goto fail;
rctx->isa = calloc(1, sizeof(struct r600_isa));
if (!rctx->isa || r600_isa_init(rctx, rctx->isa))
goto fail;
rctx->blitter = util_blitter_create(&rctx->context);

View file

@ -552,6 +552,8 @@ struct r600_context {
struct list_head dirty;
struct list_head enable_list;
unsigned pm4_dirty_cdwords;
struct r600_isa *isa;
};
static INLINE void r600_emit_command_buffer(struct radeon_winsys_cs *cs,

File diff suppressed because it is too large Load diff

View file

@ -27,7 +27,7 @@ void r700_bytecode_cf_vtx_build(uint32_t *bytecode, const struct r600_bytecode_c
{
unsigned count = (cf->ndw / 4) - 1;
*bytecode++ = S_SQ_CF_WORD0_ADDR(cf->addr >> 1);
*bytecode++ = cf->inst |
*bytecode++ = S_SQ_CF_WORD1_CF_INST(r600_isa_cf_opcode(ISA_CC_R700, cf->op)) |
S_SQ_CF_WORD1_BARRIER(1) |
S_SQ_CF_WORD1_COUNT(count) |
S_SQ_CF_WORD1_COUNT_3(count >> 3);
@ -56,7 +56,7 @@ int r700_bytecode_alu_build(struct r600_bytecode *bc, struct r600_bytecode_alu *
S_SQ_ALU_WORD1_OP3_SRC2_REL(alu->src[2].rel) |
S_SQ_ALU_WORD1_OP3_SRC2_CHAN(alu->src[2].chan) |
S_SQ_ALU_WORD1_OP3_SRC2_NEG(alu->src[2].neg) |
S_SQ_ALU_WORD1_OP3_ALU_INST(alu->inst) |
S_SQ_ALU_WORD1_OP3_ALU_INST(r600_isa_alu_opcode(bc->isa->hw_class, alu->op)) |
S_SQ_ALU_WORD1_BANK_SWIZZLE(alu->bank_swizzle);
} else {
bc->bytecode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
@ -67,7 +67,7 @@ int r700_bytecode_alu_build(struct r600_bytecode *bc, struct r600_bytecode_alu *
S_SQ_ALU_WORD1_OP2_SRC1_ABS(alu->src[1].abs) |
S_SQ_ALU_WORD1_OP2_WRITE_MASK(alu->dst.write) |
S_SQ_ALU_WORD1_OP2_OMOD(alu->omod) |
S_SQ_ALU_WORD1_OP2_ALU_INST(alu->inst) |
S_SQ_ALU_WORD1_OP2_ALU_INST(r600_isa_alu_opcode(bc->isa->hw_class, alu->op)) |
S_SQ_ALU_WORD1_BANK_SWIZZLE(alu->bank_swizzle) |
S_SQ_ALU_WORD1_OP2_UPDATE_EXECUTE_MASK(alu->execute_mask) |
S_SQ_ALU_WORD1_OP2_UPDATE_PRED(alu->update_pred);
@ -75,7 +75,8 @@ int r700_bytecode_alu_build(struct r600_bytecode *bc, struct r600_bytecode_alu *
return 0;
}
void r700_bytecode_alu_read(struct r600_bytecode_alu *alu, uint32_t word0, uint32_t word1)
void r700_bytecode_alu_read(struct r600_bytecode *bc,
struct r600_bytecode_alu *alu, uint32_t word0, uint32_t word1)
{
/* WORD0 */
alu->src[0].sel = G_SQ_ALU_WORD0_SRC0_SEL(word0);
@ -105,13 +106,15 @@ void r700_bytecode_alu_read(struct r600_bytecode_alu *alu, uint32_t word0, uint3
alu->src[2].rel = G_SQ_ALU_WORD1_OP3_SRC2_REL(word1);
alu->src[2].chan = G_SQ_ALU_WORD1_OP3_SRC2_CHAN(word1);
alu->src[2].neg = G_SQ_ALU_WORD1_OP3_SRC2_NEG(word1);
alu->inst = G_SQ_ALU_WORD1_OP3_ALU_INST(word1);
alu->op = r600_isa_alu_by_opcode(bc->isa,
G_SQ_ALU_WORD1_OP3_ALU_INST(word1), 1);
}
else /*ALU_DWORD1_OP2*/
{
alu->src[0].abs = G_SQ_ALU_WORD1_OP2_SRC0_ABS(word1);
alu->src[1].abs = G_SQ_ALU_WORD1_OP2_SRC1_ABS(word1);
alu->inst = G_SQ_ALU_WORD1_OP2_ALU_INST(word1);
alu->op = r600_isa_alu_by_opcode(bc->isa,
G_SQ_ALU_WORD1_OP2_ALU_INST(word1), 0);
alu->omod = G_SQ_ALU_WORD1_OP2_OMOD(word1);
alu->dst.write = G_SQ_ALU_WORD1_OP2_WRITE_MASK(word1);
alu->update_pred = G_SQ_ALU_WORD1_OP2_UPDATE_PRED(word1);