summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r600/sb/sb_bc_parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r600/sb/sb_bc_parser.cpp')
-rw-r--r--src/gallium/drivers/r600/sb/sb_bc_parser.cpp51
1 files changed, 34 insertions, 17 deletions
diff --git a/src/gallium/drivers/r600/sb/sb_bc_parser.cpp b/src/gallium/drivers/r600/sb/sb_bc_parser.cpp
index 017046a88a..0f642161a0 100644
--- a/src/gallium/drivers/r600/sb/sb_bc_parser.cpp
+++ b/src/gallium/drivers/r600/sb/sb_bc_parser.cpp
@@ -53,15 +53,17 @@ using std::cerr;
int bc_parser::parse() {
- dw = pipe_shader->shader.bc.bytecode;
- bc_ndw = pipe_shader->shader.bc.ndw;
+ dw = bc->bytecode;
+ bc_ndw = bc->ndw;
+ max_cf = 0;
dec = new bc_decoder(ctx, dw, bc_ndw);
shader_target t = TARGET_UNKNOWN;
- switch (pipe_shader->shader.processor_type) {
+ switch (bc->type) {
case TGSI_PROCESSOR_FRAGMENT: t = TARGET_PS; break;
case TGSI_PROCESSOR_VERTEX: t = TARGET_VS; break;
+ case TGSI_PROCESSOR_COMPUTE: t = TARGET_COMPUTE; break;
default: assert(!"unknown shader target"); return -1; break;
}
@@ -82,42 +84,43 @@ int bc_parser::parse_shader() {
bool eop = false;
sh->init();
- parse_decls();
+
+ if (pshader)
+ parse_decls();
do {
+ eop = false;
if ((r = parse_cf(i, eop)))
return r;
- } while (!eop);
+ } while (!eop || (i >> 1) <= max_cf);
return 0;
}
int bc_parser::parse_decls() {
- r600_shader &rs = pipe_shader->shader;
-
// sh->prepare_regs(rs.bc.ngpr);
- if (rs.indirect_files & ~(1 << TGSI_FILE_CONSTANT)) {
+ if (pshader->indirect_files & ~(1 << TGSI_FILE_CONSTANT)) {
#if SB_NO_ARRAY_INFO
- sh->add_gpr_array(0, rs.bc.ngpr, 0b1111);
+ sh->add_gpr_array(0, pshader->bc.ngpr, 0b1111);
#else
- assert(rs.num_arrays);
+ assert(pshader->num_arrays);
- if (rs.num_arrays) {
+ if (pshader->num_arrays) {
- for (unsigned i = 0; i < rs.num_arrays; ++i) {
- r600_shader_array &a = rs.arrays[i];
+ for (unsigned i = 0; i < pshader->num_arrays; ++i) {
+ r600_shader_array &a = pshader->arrays[i];
sh->add_gpr_array(a.gpr_start, a.gpr_count, a.comp_mask);
}
} else {
- sh->add_gpr_array(0, rs.bc.ngpr, 0b1111);
+ sh->add_gpr_array(0, pshader->bc.ngpr, 0b1111);
}
@@ -133,8 +136,8 @@ int bc_parser::parse_decls() {
unsigned linear = 0, persp = 0, centroid = 1;
- for (unsigned i = 0; i < rs.ninput; ++i) {
- r600_shader_io & in = rs.input[i];
+ for (unsigned i = 0; i < pshader->ninput; ++i) {
+ r600_shader_io & in = pshader->input[i];
bool preloaded = sh->target == TARGET_PS && !(ps_interp && in.spi_sid);
sh->add_input(in.gpr, preloaded, /*in.write_mask*/ 0b1111);
if (ps_interp && in.spi_sid) {
@@ -237,7 +240,7 @@ int bc_parser::parse_cf(unsigned &i, bool &eop) {
cf->bc.end_of_program = eop;
- } else if (flags & CF_STRM) {
+ } else if (flags & (CF_STRM | CF_RAT)) {
assert(!cf->bc.rw_rel);
unsigned burst_count = cf->bc.burst_count;
@@ -256,6 +259,17 @@ int bc_parser::parse_cf(unsigned &i, bool &eop) {
sh->get_gpr_value(true, cf->bc.rw_gpr, s, false);
}
+ if ((flags & CF_RAT) && (cf->bc.type & 1)) { // indexed write
+ cf->src.resize(8);
+ for(int s = 0; s < 3; ++s) {
+ cf->src[4 + s] =
+ sh->get_gpr_value(true, cf->bc.index_gpr, s, false);
+ }
+
+ // FIXME probably we can relax it a bit
+ cf->flags |= NF_DONT_HOIST | NF_DONT_MOVE;
+ }
+
if (!burst_count--)
break;
@@ -271,6 +285,9 @@ int bc_parser::parse_cf(unsigned &i, bool &eop) {
} else if (cf->bc.op == CF_OP_CALL_FS) {
sh->init_call_fs(cf);
cf->flags |= NF_SCHEDULE_EARLY | NF_DONT_MOVE;
+ } else if (flags & CF_BRANCH) {
+ if (cf->bc.addr > max_cf)
+ max_cf = cf->bc.addr;
}
eop = cf->bc.end_of_program || cf->bc.op == CF_OP_CF_END;