[Mesa-dev] [PATCH 8/9] r600g/sb: Add dependency tracking for scratch ops
Glenn Kennard
glenn.kennard at gmail.com
Sun Mar 5 17:26:53 UTC 2017
Signed-off-by: Glenn Kennard <glenn.kennard at gmail.com>
---
src/gallium/drivers/r600/r600_shader.h | 1 +
src/gallium/drivers/r600/sb/sb_bc_finalize.cpp | 2 +-
src/gallium/drivers/r600/sb/sb_bc_parser.cpp | 12 ++++++++++++
src/gallium/drivers/r600/sb/sb_core.cpp | 3 ++-
src/gallium/drivers/r600/sb/sb_ir.h | 6 +++++-
src/gallium/drivers/r600/sb/sb_ra_init.cpp | 2 +-
src/gallium/drivers/r600/sb/sb_sched.cpp | 2 +-
src/gallium/drivers/r600/sb/sb_valtable.cpp | 1 +
8 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h
index e94230f..3c35d48 100644
--- a/src/gallium/drivers/r600/r600_shader.h
+++ b/src/gallium/drivers/r600/r600_shader.h
@@ -67,6 +67,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 82826a9..5d74794 100644
--- a/src/gallium/drivers/r600/sb/sb_bc_finalize.cpp
+++ b/src/gallium/drivers/r600/sb/sb_bc_finalize.cpp
@@ -293,7 +293,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());
+ assert((n->bc.op_ptr->flags & AF_MOVA) || d->is_geometry_emit() || 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 ae92a76..9c52342 100644
--- a/src/gallium/drivers/r600/sb/sb_bc_parser.cpp
+++ b/src/gallium/drivers/r600/sb/sb_bc_parser.cpp
@@ -667,6 +667,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;
@@ -797,6 +802,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;
@@ -831,6 +840,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 afea818..283c84f 100644
--- a/src/gallium/drivers/r600/sb/sb_core.cpp
+++ b/src/gallium/drivers/r600/sb/sb_core.cpp
@@ -191,7 +191,8 @@ 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)
+ // Same for for shaders spilling to scratch memory using SV_SCRATCH
+ if (sh->target != TARGET_GS || 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 74c0549..141bf5f 100644
--- a/src/gallium/drivers/r600/sb/sb_ir.h
+++ b/src/gallium/drivers/r600/sb/sb_ir.h
@@ -42,7 +42,8 @@ enum special_regs {
SV_EXEC_MASK,
SV_AR_INDEX,
SV_VALID_MASK,
- SV_GEOMETRY_EMIT
+ SV_GEOMETRY_EMIT,
+ SV_SCRATCH
};
class node;
@@ -514,6 +515,9 @@ public:
bool is_geometry_emit() {
return is_special_reg() && select == sel_chan(SV_GEOMETRY_EMIT, 0);
}
+ bool is_scratch() {
+ return is_special_reg() && select == sel_chan(SV_SCRATCH, 0);
+ }
node* any_def() {
assert(!(def && adef));
diff --git a/src/gallium/drivers/r600/sb/sb_ra_init.cpp b/src/gallium/drivers/r600/sb/sb_ra_init.cpp
index 68ee982..c2f4b6a 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 5113b75..22cd6a0 100644
--- a/src/gallium/drivers/r600/sb/sb_sched.cpp
+++ b/src/gallium/drivers/r600/sb/sb_sched.cpp
@@ -1649,7 +1649,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());
+ assert((a->bc.op_ptr->flags & AF_MOVA) || d->is_geometry_emit() || 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 d31a1b7..8f2924e 100644
--- a/src/gallium/drivers/r600/sb/sb_valtable.cpp
+++ b/src/gallium/drivers/r600/sb/sb_valtable.cpp
@@ -56,6 +56,7 @@ sb_ostream& operator << (sb_ostream &o, value &v) {
case SV_EXEC_MASK: o << "EM"; break;
case SV_VALID_MASK: o << "VM"; break;
case SV_GEOMETRY_EMIT: o << "GEOMETRY_EMIT"; break;
+ case SV_SCRATCH: o << "SCRATCH"; break;
default: o << "???specialreg"; break;
}
break;
--
2.7.4
More information about the mesa-dev
mailing list