True, I skipped a step in my comment. My assumption is that ACPI and UEFI/BIOS usually exist together. Without UEFI you have to find an alternative to both, and neither DTs and the (bootloader) alternatives are pleasant.
ACPI table issues are just as unpleasant as devicetrees if not moreso.
What makes x86 feel nicer is that most of the peripherals fall into two categories: 1) Standardized for the arch, so their configuration can be assumed and hardcoded, or 2) Attached to a bus that can be dynamically enumerated (i.e. USB, PCI, etc.) This generally makes the per-system configuration relatively simple.
Embedded systems are not like this. Each SoC is effectively its own system architecture that just happens to share a CPU instruction set with other systems, and the devicetree ends up being the description of this architecture. So it looks gross and ugly and complex by comparison, but the complexity of defining peripherals for a system has to exist somewhere!
The messy bits are, of course, that both the OS and bootloader need access to subsets of this data, and you'd like to ship the tables with the bootloader for a SoC (so the OS can be gneeric and not care), but really, the bootloader only needs a little bit of this, and the OS needs almost all of it... and this leads to coupling between the two being tighter than it should be.
What's so wrong with u-boot? Most of the trouble people have with it is "thanks" to chipset vendors who forked their version somewhere 10-ish years ago and completely mutilated it instead of putting in the effort to get their stuff upstreamed.
The only major thing it can't boot to my knowledge is Windows, but it might be doable if you chain-load Grub.
uboot needs to be modified to run a given operating system if it wasn't already supported (or a shim pretending to be one of the supported operating systems needs to be used). UEFI provides a way to support all operating systems through a standardized interface. uboot implementing UEFI interface provides the best of both worlds.