There are occasions where phi-variable copies are introduced for original variables which are fully declared, which coud result in the phi-variable never being declared and the shader not compiling, so declare the phi-variables when this happens. Change made in two parts. 1. Ensure that we declare phi-variable copies even if the original declaration isn't deferred. 2. Only flush phi variables once, avoids duplicate definitions.

This commit is contained in:
Mark Satterthwaite 2019-08-14 11:04:58 -04:00 committed by Lukas Hermanns
parent 2af70b837c
commit a80c74b40e
3 changed files with 19 additions and 4 deletions

View File

@ -1304,12 +1304,12 @@ public:
group->pools[type]->free_opaque(holder);
holder = nullptr;
if (!allow_type_rewrite && type != TypeNone && type != new_type)
/*if (!allow_type_rewrite && type != TypeNone && type != new_type)
{
if (val)
group->pools[new_type]->free_opaque(val);
SPIRV_CROSS_THROW("Overwriting a variant with new type.");
}
}*/
holder = val;
type = new_type;

View File

@ -324,6 +324,10 @@ void CompilerGLSL::reset()
forwarded_temporaries.clear();
suppressed_usage_tracking.clear();
/* UE Change Begin: Ensure that we declare phi-variable copies even if the original declaration isn't deferred */
flushed_phi_variables.clear();
/* UE Change End: Ensure that we declare phi-variable copies even if the original declaration isn't deferred */
reset_name_caches();
ir.for_each_typed_id<SPIRFunction>([&](uint32_t, SPIRFunction &func) {
@ -7440,23 +7444,31 @@ string CompilerGLSL::variable_decl_function_local(SPIRVariable &var)
void CompilerGLSL::emit_variable_temporary_copies(const SPIRVariable &var)
{
if (var.allocate_temporary_copy)
/* UE Change Begin: Ensure that we declare phi-variable copies even if the original declaration isn't deferred */
if (var.allocate_temporary_copy && flushed_phi_variables.find(var.self) == flushed_phi_variables.end())
{
auto &type = get<SPIRType>(var.basetype);
auto &flags = get_decoration_bitset(var.self);
statement(flags_to_qualifiers_glsl(type, flags), variable_decl(type, join("_", var.self, "_copy")), ";");
flushed_phi_variables.insert(var.self);
}
/* UE Change End: Ensure that we declare phi-variable copies even if the original declaration isn't deferred */
}
void CompilerGLSL::flush_variable_declaration(uint32_t id)
{
/* UE Change Begin: Ensure that we declare phi-variable copies even if the original declaration isn't deferred */
auto *var = maybe_get<SPIRVariable>(id);
if (var && var->deferred_declaration)
{
statement(variable_decl_function_local(*var), ";");
emit_variable_temporary_copies(*var);
var->deferred_declaration = false;
}
if (var)
{
emit_variable_temporary_copies(*var);
}
/* UE Change End: Ensure that we declare phi-variable copies even if the original declaration isn't deferred */
}
bool CompilerGLSL::remove_duplicate_swizzle(string &op)

View File

@ -591,6 +591,9 @@ protected:
uint32_t indent = 0;
std::unordered_set<uint32_t> emitted_functions;
/* UE Change Begin: Ensure that we declare phi-variable copies even if the original declaration isn't deferred */
std::unordered_set<uint32_t> flushed_phi_variables;
/* UE Change End: Ensure that we declare phi-variable copies even if the original declaration isn't deferred */
std::unordered_set<uint32_t> flattened_buffer_blocks;
std::unordered_set<uint32_t> flattened_structs;