mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-26 17:10:11 +01:00
intel/fs: Calculate SWSB cross-pipeline synchronization information.
In combination with the previous changes we can just check whether an instruction has any potentially unsatisfied dependencies on more than one pipeline, and if so use TGL_PIPE_ALL synchronization with an appropriate RegDist counter, otherwise synchronize with the single pipeline it has a dependency on, if any. Only minor difficulty is caused by the fact that the hardware doesn't have any way to encode pipeline information when a RegDist and an SBID dependency need to be provided simultaneously, in which case the synchronization pipeline is inferred by the hardware. We need to verify that the hardware's inference will give the correct result (which may not be the case if e.g. some data was bit-cast from a different type), and if not emit separate SYNC instructions instead of baking the RegDist dependency into the instruction (Note that SET SBID dependencies must always be baked into the corresponding out-of-order instruction). Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10000>
This commit is contained in:
parent
3f063334fc
commit
d57f3ced6c
1 changed files with 48 additions and 8 deletions
|
|
@ -816,6 +816,7 @@ namespace {
|
|||
const ordered_address &jp,
|
||||
bool exec_all)
|
||||
{
|
||||
tgl_pipe p = TGL_PIPE_NONE;
|
||||
unsigned min_dist = ~0u;
|
||||
|
||||
for (unsigned i = 0; i < deps.size(); i++) {
|
||||
|
|
@ -824,13 +825,16 @@ namespace {
|
|||
const unsigned dist = jp.jp[q] - int64_t(deps[i].jp.jp[q]);
|
||||
const unsigned max_dist = (q == IDX(TGL_PIPE_LONG) ? 14 : 10);
|
||||
assert(jp.jp[q] > deps[i].jp.jp[q]);
|
||||
if (dist <= max_dist)
|
||||
if (dist <= max_dist) {
|
||||
p = (p && IDX(p) != q ? TGL_PIPE_ALL :
|
||||
tgl_pipe(TGL_PIPE_FLOAT + q));
|
||||
min_dist = MIN3(min_dist, dist, 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { min_dist == ~0u ? 0 : min_dist };
|
||||
return { p ? min_dist : 0, p };
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -877,19 +881,22 @@ namespace {
|
|||
* dependency is present.
|
||||
*/
|
||||
tgl_sbid_mode
|
||||
baked_unordered_dependency_mode(const fs_inst *inst,
|
||||
baked_unordered_dependency_mode(const struct gen_device_info *devinfo,
|
||||
const fs_inst *inst,
|
||||
const dependency_list &deps,
|
||||
const ordered_address &jp)
|
||||
{
|
||||
const bool exec_all = inst->force_writemask_all;
|
||||
const bool has_ordered = find_ordered_dependency(deps, jp, exec_all);
|
||||
const tgl_pipe ordered_pipe = ordered_dependency_swsb(deps, jp,
|
||||
exec_all).pipe;
|
||||
|
||||
if (find_unordered_dependency(deps, TGL_SBID_SET, exec_all))
|
||||
return find_unordered_dependency(deps, TGL_SBID_SET, exec_all);
|
||||
else if (has_ordered && is_unordered(inst))
|
||||
return TGL_SBID_NULL;
|
||||
else if (find_unordered_dependency(deps, TGL_SBID_DST, exec_all) &&
|
||||
(!has_ordered || !is_unordered(inst)))
|
||||
(!has_ordered || ordered_pipe == inferred_sync_pipe(devinfo, inst)))
|
||||
return find_unordered_dependency(deps, TGL_SBID_DST, exec_all);
|
||||
else if (!has_ordered)
|
||||
return find_unordered_dependency(deps, TGL_SBID_SRC, exec_all);
|
||||
|
|
@ -897,6 +904,34 @@ namespace {
|
|||
return TGL_SBID_NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether an ordered dependency from the list \p deps can be
|
||||
* represented directly in the SWSB annotation of the instruction without
|
||||
* additional SYNC instructions.
|
||||
*/
|
||||
bool
|
||||
baked_ordered_dependency_mode(const struct gen_device_info *devinfo,
|
||||
const fs_inst *inst,
|
||||
const dependency_list &deps,
|
||||
const ordered_address &jp)
|
||||
{
|
||||
const bool exec_all = inst->force_writemask_all;
|
||||
const bool has_ordered = find_ordered_dependency(deps, jp, exec_all);
|
||||
const tgl_pipe ordered_pipe = ordered_dependency_swsb(deps, jp,
|
||||
exec_all).pipe;
|
||||
const tgl_sbid_mode unordered_mode =
|
||||
baked_unordered_dependency_mode(devinfo, inst, deps, jp);
|
||||
|
||||
if (!has_ordered)
|
||||
return false;
|
||||
else if (!unordered_mode)
|
||||
return true;
|
||||
else
|
||||
return ordered_pipe == inferred_sync_pipe(devinfo, inst) &&
|
||||
unordered_mode == (is_unordered(inst) ? TGL_SBID_SET :
|
||||
TGL_SBID_DST);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
|
@ -1134,13 +1169,17 @@ namespace {
|
|||
const ordered_address *jps,
|
||||
const dependency_list *deps)
|
||||
{
|
||||
const struct gen_device_info *devinfo = shader->devinfo;
|
||||
unsigned ip = 0;
|
||||
|
||||
foreach_block_and_inst_safe(block, fs_inst, inst, shader->cfg) {
|
||||
const bool exec_all = inst->force_writemask_all;
|
||||
tgl_swsb swsb = ordered_dependency_swsb(deps[ip], jps[ip], exec_all);
|
||||
const bool ordered_mode =
|
||||
baked_ordered_dependency_mode(devinfo, inst, deps[ip], jps[ip]);
|
||||
const tgl_sbid_mode unordered_mode =
|
||||
baked_unordered_dependency_mode(inst, deps[ip], jps[ip]);
|
||||
baked_unordered_dependency_mode(devinfo, inst, deps[ip], jps[ip]);
|
||||
tgl_swsb swsb = !ordered_mode ? tgl_swsb() :
|
||||
ordered_dependency_swsb(deps[ip], jps[ip], exec_all);
|
||||
|
||||
for (unsigned i = 0; i < deps[ip].size(); i++) {
|
||||
const dependency &dep = deps[ip][i];
|
||||
|
|
@ -1174,8 +1213,9 @@ namespace {
|
|||
for (unsigned i = 0; i < deps[ip].size(); i++) {
|
||||
const dependency &dep = deps[ip][i];
|
||||
|
||||
if (dep.ordered && dep.exec_all > exec_all &&
|
||||
find_ordered_dependency(deps[ip], jps[ip], true)) {
|
||||
if (dep.ordered &&
|
||||
find_ordered_dependency(deps[ip], jps[ip], true) &&
|
||||
(!ordered_mode || dep.exec_all > exec_all)) {
|
||||
/* If the current instruction is not marked NoMask but an
|
||||
* ordered dependency is, perform the synchronization as a
|
||||
* separate NoMask SYNC instruction in order to avoid data
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue