The result of an AccessChain intrinsic in SPIRV can be referenced by multiple blocks but when they are loops that can result in compilation problems because the source variables might not be declared early enough. This forces us to hoist those variables high enough to make it work.
This commit is contained in:
parent
a80c74b40e
commit
869d628521
@ -2730,6 +2730,13 @@ void Compiler::AnalyzeVariableScopeAccessHandler::notify_variable_access(uint32_
|
||||
{
|
||||
if (id == 0)
|
||||
return;
|
||||
|
||||
/* UE Change Begin: Access chains used in multiple blocks mean hoisting all the variables used to construct the access chain as not all backends can use pointers. */
|
||||
for (auto child_id : access_chain_children[id])
|
||||
{
|
||||
notify_variable_access(child_id, block);
|
||||
}
|
||||
/* UE Change End: Access chains used in multiple blocks mean hoisting all the variables used to construct the access chain as not all backends can use pointers. */
|
||||
|
||||
if (id_is_phi_variable(id))
|
||||
accessed_variables_to_block[id].insert(block);
|
||||
@ -2795,14 +2802,22 @@ bool Compiler::AnalyzeVariableScopeAccessHandler::handle(spv::Op op, const uint3
|
||||
if (length < 3)
|
||||
return false;
|
||||
|
||||
/* UE Change Begin: Access chains used in multiple blocks mean hoisting all the variables used to construct the access chain as not all backends can use pointers. */
|
||||
uint32_t ptr = args[2];
|
||||
auto *var = compiler.maybe_get<SPIRVariable>(ptr);
|
||||
if (var)
|
||||
{
|
||||
accessed_variables_to_block[var->self].insert(current_block->self);
|
||||
access_chain_children[args[1]].insert(var->self);
|
||||
}
|
||||
|
||||
// args[2] might be another access chain we have to track use of.
|
||||
for (uint32_t i = 2; i < length; i++)
|
||||
{
|
||||
notify_variable_access(args[i], current_block->self);
|
||||
access_chain_children[args[1]].insert(args[i]);
|
||||
}
|
||||
/* UE Change End: Access chains used in multiple blocks mean hoisting all the variables used to construct the access chain as not all backends can use pointers. */
|
||||
|
||||
// Also keep track of the access chain pointer itself.
|
||||
// In exceptionally rare cases, we can end up with a case where
|
||||
|
@ -919,6 +919,9 @@ protected:
|
||||
std::unordered_map<uint32_t, std::unordered_set<uint32_t>> complete_write_variables_to_block;
|
||||
std::unordered_map<uint32_t, std::unordered_set<uint32_t>> partial_write_variables_to_block;
|
||||
std::unordered_set<uint32_t> access_chain_expressions;
|
||||
/* UE Change Begin: Access chains used in multiple blocks mean hoisting all the variables used to construct the access chain as not all backends can use pointers. */
|
||||
std::unordered_map<uint32_t, std::unordered_set<uint32_t>> access_chain_children;
|
||||
/* UE Change End: Access chains used in multiple blocks mean hoisting all the variables used to construct the access chain as not all backends can use pointers. */
|
||||
const SPIRBlock *current_block = nullptr;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user