Global immutable or global mutable. I vehemently agree with the latter, but while I could definitely make a case for the former [1], I think it is a bit too extreme especially without language support.
Would you access a global M_PI constant? Or another function name? Or would you require every dependency to passed through?
[1] i.e. a total capability based system.
Global mutable state is to be avoided at all costs of course, but IMO global immutable state is to be avoided... at some costs.
The main issue comes in when you change (in the code! not as mutation!) the global immutable state and now you have to track down a bunch of usages. If it wasn't global, you could change it only in some local areas and not others.
You aren't likely to change M_PI to a new value (int 3 for performance?) so for pure constants, fine, global immutable state works. However many usages of global state are things like singletons, loggers and string messages that often eventually benefit from being passed in (i18n, testability etc.)
As to ergonomics, you can stuff all that global state into a single instance and have one more parameter that is passed around. It will still allow calls to eg change logging on their downstream functions much more easily than having singleton configuration.