My state university (UMass) education's CS degree had us working directly with CPUs and logic gates on breadboards (made an ALU!) We even designed our own x86-like CPU ISA to be run via simulation with our own progams. We built and programed robots from discrete components and microcontrollers written in assembly. Made our own rudimentary OS, including threading with mutexes and semaphores. Built our own pine-like terminal email client from scratch. Created design docs for our own games and executed on them in sprint teams throughout the semesters.
I cannot stress how important my education was to my current understanding and success as a software engineer in the field. A poor education is a huge detriment. When I joined the workforce I found many colleagues without one ill prepared for some of the basics, like debugging kills, using tools outside their domain expertise, etc.
That said I don't think a formal education is REQUIRED, but without one you need a certain kind of perseverance and thirst for knowledge not everyone has. I've had the pleasure of working with several folks in that category, so a formal degree isn't for everyone.
Today, it appears specialization is happening much earlier in the education process without a general foundation. Specialists will always be needed, and larger orgs can get by just fine with exclusively specialists, as long as their communication skills exist to prevent silos. Larger companies can afford this. However a good generalist can replace a team of specialists when the latter budget is out of the question; a huge win for smaller orgs, start-ups etc.
The old joke that a good generalist is the "jack of all trades, master of none" has some truth to it, but as with all things, it's a tradeoff. A team of qualified specialists will definitely produce better work within their domain expertise, but at a cost that can be prohibitive when "good enough" is within reach.