From: Glenn Kennard Date: Sun, 5 Mar 2017 17:26:53 +0000 (+0100) Subject: r600g/sb: Add dependency tracking for scratch ops X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cd34deb585669ffe1d520b07c629316f2ac22074;p=mesa.git r600g/sb: Add dependency tracking for scratch ops Signed-off-by: Glenn Kennard Reviewed-by: Dave Airlie --- diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h index b837d1309ae..3b3e667ec56 100644 --- a/src/gallium/drivers/r600/r600_shader.h +++ b/src/gallium/drivers/r600/r600_shader.h @@ -78,6 +78,7 @@ struct r600_shader { boolean uses_kill; boolean fs_write_all; boolean two_side; + boolean needs_scratch_space; /* Number of color outputs in the TGSI shader, * sometimes it could be higher than nr_cbufs (bug?). * Also with writes_all property on eg+ it will be set to max CB number */ diff --git a/src/gallium/drivers/r600/sb/sb_bc_finalize.cpp b/src/gallium/drivers/r600/sb/sb_bc_finalize.cpp index d3fab800204..e737f3d6cd0 100644 --- a/src/gallium/drivers/r600/sb/sb_bc_finalize.cpp +++ b/src/gallium/drivers/r600/sb/sb_bc_finalize.cpp @@ -311,7 +311,7 @@ void bc_finalizer::finalize_alu_group(alu_group_node* g, node *prev_node) { value *d = n->dst.empty() ? NULL : n->dst[0]; if (d && d->is_special_reg()) { - assert((n->bc.op_ptr->flags & AF_MOVA) || d->is_geometry_emit() || d->is_lds_oq() || d->is_lds_access()); + assert((n->bc.op_ptr->flags & AF_MOVA) || d->is_geometry_emit() || d->is_lds_oq() || d->is_lds_access() || d->is_scratch()); d = NULL; } diff --git a/src/gallium/drivers/r600/sb/sb_bc_parser.cpp b/src/gallium/drivers/r600/sb/sb_bc_parser.cpp index 87035ee2a6b..2ec842159b1 100644 --- a/src/gallium/drivers/r600/sb/sb_bc_parser.cpp +++ b/src/gallium/drivers/r600/sb/sb_bc_parser.cpp @@ -725,6 +725,11 @@ int bc_parser::prepare_fetch_clause(cf_node *cf) { n->src.push_back(get_cf_index_value(n->bc.resource_index_mode == V_SQ_CF_INDEX_1)); } } + + if (n->bc.op == FETCH_OP_READ_SCRATCH) { + n->src.push_back(sh->get_special_value(SV_SCRATCH)); + n->dst.push_back(sh->get_special_value(SV_SCRATCH)); + } } return 0; @@ -855,6 +860,10 @@ int bc_parser::prepare_ir() { c->flags |= NF_DONT_KILL; } } + else if (c->bc.op == CF_OP_MEM_SCRATCH) { + c->src.push_back(sh->get_special_value(SV_SCRATCH)); + c->dst.push_back(sh->get_special_value(SV_SCRATCH)); + } if (!burst_count--) break; @@ -889,6 +898,9 @@ int bc_parser::prepare_ir() { c->src.push_back(sh->get_special_value(SV_GEOMETRY_EMIT)); c->dst.push_back(sh->get_special_value(SV_GEOMETRY_EMIT)); } + } else if (c->bc.op == CF_OP_WAIT_ACK) { + c->src.push_back(sh->get_special_value(SV_SCRATCH)); + c->dst.push_back(sh->get_special_value(SV_SCRATCH)); } } diff --git a/src/gallium/drivers/r600/sb/sb_core.cpp b/src/gallium/drivers/r600/sb/sb_core.cpp index 5049b677842..a94d8d32b50 100644 --- a/src/gallium/drivers/r600/sb/sb_core.cpp +++ b/src/gallium/drivers/r600/sb/sb_core.cpp @@ -191,7 +191,7 @@ int r600_sb_bytecode_process(struct r600_context *rctx, // if conversion breaks the dependency tracking between CF_EMIT ops when it removes // the phi nodes for SV_GEOMETRY_EMIT. Just disable it for GS - if (sh->target != TARGET_GS && sh->target != TARGET_HS) + if ((sh->target != TARGET_GS && sh->target != TARGET_HS) || pshader->needs_scratch_space) SB_RUN_PASS(if_conversion, 1); // if_conversion breaks info about uses, but next pass (peephole) diff --git a/src/gallium/drivers/r600/sb/sb_ir.h b/src/gallium/drivers/r600/sb/sb_ir.h index bee947504ed..245af961e69 100644 --- a/src/gallium/drivers/r600/sb/sb_ir.h +++ b/src/gallium/drivers/r600/sb/sb_ir.h @@ -46,6 +46,7 @@ enum special_regs { SV_LDS_RW, SV_LDS_OQA, SV_LDS_OQB, + SV_SCRATCH }; class node; @@ -517,6 +518,9 @@ public: v = v->gvn_source; return v; } + bool is_scratch() { + return is_special_reg() && select == sel_chan(SV_SCRATCH, 0); + } bool is_float_0_or_1() { value *v = gvalue(); diff --git a/src/gallium/drivers/r600/sb/sb_ra_init.cpp b/src/gallium/drivers/r600/sb/sb_ra_init.cpp index e5ec9db23b7..985e1794523 100644 --- a/src/gallium/drivers/r600/sb/sb_ra_init.cpp +++ b/src/gallium/drivers/r600/sb/sb_ra_init.cpp @@ -708,7 +708,7 @@ void ra_split::split_vec(vvec &vv, vvec &v1, vvec &v2, bool allow_swz) { assert(!o->is_dead()); - if (o->is_undef() || o->is_geometry_emit()) + if (o->is_undef() || o->is_geometry_emit() || o->is_scratch()) continue; if (allow_swz && o->is_float_0_or_1()) diff --git a/src/gallium/drivers/r600/sb/sb_sched.cpp b/src/gallium/drivers/r600/sb/sb_sched.cpp index f5fd84d54ac..ffc66018b10 100644 --- a/src/gallium/drivers/r600/sb/sb_sched.cpp +++ b/src/gallium/drivers/r600/sb/sb_sched.cpp @@ -1670,7 +1670,7 @@ unsigned post_scheduler::try_add_instruction(node *n) { value *d = a->dst.empty() ? NULL : a->dst[0]; if (d && d->is_special_reg()) { - assert((a->bc.op_ptr->flags & AF_MOVA) || d->is_geometry_emit() || d->is_lds_oq() || d->is_lds_access()); + assert((a->bc.op_ptr->flags & AF_MOVA) || d->is_geometry_emit() || d->is_lds_oq() || d->is_lds_access() || d->is_scratch()); d = NULL; } diff --git a/src/gallium/drivers/r600/sb/sb_valtable.cpp b/src/gallium/drivers/r600/sb/sb_valtable.cpp index 41cfbf0946a..dd336bc4177 100644 --- a/src/gallium/drivers/r600/sb/sb_valtable.cpp +++ b/src/gallium/drivers/r600/sb/sb_valtable.cpp @@ -59,6 +59,7 @@ sb_ostream& operator << (sb_ostream &o, value &v) { case SV_LDS_RW: o << "LDS_RW"; break; case SV_LDS_OQA: o << "LDS_OQA"; break; case SV_LDS_OQB: o << "LDS_OQB"; break; + case SV_SCRATCH: o << "SCRATCH"; break; default: o << "???specialreg"; break; } break;