diff --git a/spirv_common.hpp b/spirv_common.hpp index b599e0335..8e3a3ec55 100644 --- a/spirv_common.hpp +++ b/spirv_common.hpp @@ -748,6 +748,10 @@ struct SPIRExpression : IVariant // A list of expressions which this expression depends on. SmallVector expression_dependencies; + // Similar as expression dependencies, but does not stop the tracking for force-temporary variables. + // We need to know the full chain from store back to any SSA variable. + SmallVector invariance_dependencies; + // By reading this expression, we implicitly read these expressions as well. // Used by access chain Store and Load since we read multiple expressions in this case. SmallVector implied_read_expressions; diff --git a/spirv_cross.cpp b/spirv_cross.cpp index 5471b3515..3492f0b3e 100644 --- a/spirv_cross.cpp +++ b/spirv_cross.cpp @@ -2569,6 +2569,15 @@ void Compiler::add_active_interface_variable(uint32_t var_id) void Compiler::inherit_expression_dependencies(uint32_t dst, uint32_t source_expression) { + auto *ptr_e = maybe_get(dst); + + if (is_position_invariant() && ptr_e && maybe_get(source_expression)) + { + auto &deps = ptr_e->invariance_dependencies; + if (std::find(deps.begin(), deps.end(), source_expression) == deps.end()) + deps.push_back(source_expression); + } + // Don't inherit any expression dependencies if the expression in dst // is not a forwarded temporary. if (forwarded_temporaries.find(dst) == end(forwarded_temporaries) || @@ -2577,7 +2586,7 @@ void Compiler::inherit_expression_dependencies(uint32_t dst, uint32_t source_exp return; } - auto &e = get(dst); + auto &e = *ptr_e; auto *phi = maybe_get(source_expression); if (phi && phi->phi_variable) { diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index 6ff54e219..a5e8a4453 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -11772,7 +11772,7 @@ void CompilerGLSL::disallow_forwarding_in_expression_chain(const SPIRExpression force_temporary_and_recompile(expr.self); forced_invariant_temporaries.insert(expr.self); - for (auto &dependent : expr.expression_dependencies) + for (auto &dependent : expr.invariance_dependencies) disallow_forwarding_in_expression_chain(get(dependent)); } }