@@ -434,7 +434,7 @@ SPIRVariable *Compiler::maybe_get_backing_variable(uint32_t chain)
434434 return var;
435435}
436436
437- const SPIRExpression *Compiler::maybe_get_backing_buffer_pointer (uint32_t chain) const
437+ SPIRExpression *Compiler::maybe_get_backing_buffer_pointer (uint32_t chain)
438438{
439439 auto *expr = maybe_get<SPIRExpression>(chain);
440440 while (expr && !expr->buffer_pointer && expr->loaded_from )
@@ -446,6 +446,7 @@ void Compiler::register_read(uint32_t expr, uint32_t chain, bool forwarded)
446446{
447447 auto &e = get<SPIRExpression>(expr);
448448 auto *var = maybe_get_backing_variable (chain);
449+ auto *buffer_pointer = maybe_get_backing_buffer_pointer (chain);
449450
450451 if (var)
451452 {
@@ -460,6 +461,13 @@ void Compiler::register_read(uint32_t expr, uint32_t chain, bool forwarded)
460461 if (var && var->parameter )
461462 var->parameter ->read_count ++;
462463 }
464+ else if (buffer_pointer)
465+ {
466+ e.loaded_from = buffer_pointer->self ;
467+ // If the backing variable is immutable, we do not need to depend on the variable.
468+ if (forwarded && !is_immutable (buffer_pointer->self ))
469+ buffer_pointer->buffer_pointer_dependees .push_back (e.self );
470+ }
463471}
464472
465473void Compiler::register_write (uint32_t chain)
@@ -477,6 +485,8 @@ void Compiler::register_write(uint32_t chain)
477485 var = maybe_get<SPIRVariable>(access_chain->loaded_from );
478486 }
479487
488+ auto *buffer_pointer = maybe_get_backing_buffer_pointer (chain);
489+
480490 auto &chain_type = expression_type (chain);
481491
482492 if (var)
@@ -487,12 +497,7 @@ void Compiler::register_write(uint32_t chain)
487497 // If our variable is in a storage class which can alias with other buffers,
488498 // invalidate all variables which depend on aliased variables. And if this is a
489499 // variable pointer, then invalidate all variables regardless.
490- if (BuiltIn (get_decoration (var->self , DecorationBuiltIn)) == BuiltInResourceHeapEXT)
491- {
492- // Very free form aliasing, be conservative.
493- flush_all_active_variables ();
494- }
495- else if (get_variable_data_type (*var).pointer )
500+ if (get_variable_data_type (*var).pointer )
496501 {
497502 flush_all_active_variables ();
498503
@@ -526,6 +531,10 @@ void Compiler::register_write(uint32_t chain)
526531 force_recompile ();
527532 }
528533 }
534+ else if (buffer_pointer)
535+ {
536+ flush_dependees (*buffer_pointer);
537+ }
529538 else if (chain_type.pointer )
530539 {
531540 // If we stored through a variable pointer, then we don't know which
@@ -547,6 +556,16 @@ void Compiler::flush_dependees(SPIRVariable &var)
547556 var.dependees .clear ();
548557}
549558
559+ void Compiler::flush_dependees (SPIRExpression &expr)
560+ {
561+ // A little ugly to split things up like this since BufferPointerEXT is a weird case
562+ // where it's both an expression (chain into global heap) and a memory declaration at the same time ...
563+ assert (expr.buffer_pointer );
564+ for (auto dep : expr.buffer_pointer_dependees )
565+ invalid_expressions.insert (dep);
566+ expr.buffer_pointer_dependees .clear ();
567+ }
568+
550569void Compiler::flush_all_aliased_variables ()
551570{
552571 for (auto aliased : aliased_variables)
@@ -557,6 +576,8 @@ void Compiler::flush_all_atomic_capable_variables()
557576{
558577 for (auto global : global_variables)
559578 flush_dependees (get<SPIRVariable>(global));
579+ for (auto global : buffer_pointer_variables)
580+ flush_dependees (get<SPIRExpression>(global));
560581 flush_all_aliased_variables ();
561582}
562583
@@ -578,6 +599,8 @@ void Compiler::flush_all_active_variables()
578599 flush_dependees (get<SPIRVariable>(arg.id ));
579600 for (auto global : global_variables)
580601 flush_dependees (get<SPIRVariable>(global));
602+ for (auto global : buffer_pointer_variables)
603+ flush_dependees (get<SPIRExpression>(global));
581604
582605 flush_all_aliased_variables ();
583606}
0 commit comments