In principle there's no longer any reason why it has to work this way, because now we have shaders. These are a more domain-specific tool than a C API, and can thus safely present large cross-sections of graphics card functionality in a higher-level way without taking power away from the graphics programmer. So, for example, people modding Minecraft can introduce their own visual effects stages by hotloading shaders into the standard Minecraft graphics pipeline.
EDIT: I haven't talked about performance. For game developers, rendering a frame quickly is as important as having total control over the output of the rendering process. For the most part, building an API higher-level than OpenGL also means dictating a particular scene graph structure, as with OS-specific window system APIs. If the API imposes a certain way of organizing your scene graph, this can have serious impacts on your game's performance, because the scene graph traversal is optimized for one type of scene and you're using it for another. I'm not sure I'm simplifying this explanation very well, but that's the gist of it.
> these APIs are very thin abstractions over the actual assembly-level instructions sent to the graphics card
If only this were the case... The drivers end up doing quite a bit, to the point where most renderers spend most of their time waiting for the driver to return. This is part of the reason Mantle was a big deal, and why DX12 and GL5 promise to be lower level.
> In principle there's no longer any reason why it has to work this way, because now we have shaders
Shaders don't replace all the fixed function parts of the GPU, and they don't try to. Maybe someday they'll replace more of it, but there are still several fixed function stages in the rendering pipeline.
Not to mention, setting GPU state will pretty much always be completely independent from shaders, and required for many visual effects. D3D or CG FX files try to abstract this, but I don't think they're popular anymore.
> For the most part, building an API higher-level than OpenGL also means dictating a particular scene graph structure...
The general premise that any layer on top of the driver will limit on the way you structure the renderer is accurate, but scene graphs are an antipattern inside a modern renderer. Plenty of engines use them for higher level organization, but keep it far away from the renderer. All that pointer chasing murders the cache.
> Drivers should not crash the GPU or CPU, or lock up when called in undefined ways via the API
runs directly counter to this complaint:
> They will not bother to re-write their entire rendering pipeline to use super-aggressive batching, etc. like the GL community has been recently recommending to get perf up.
Error checking = higher per call overhead = slower performance.
If you think there should be a way to turn on a sort of safe-mode or something where the driver holds your hand that sounds reasonable, except for this:
> I've seen major shipped GL apps with per-frame GL errors. (Is this normal? Does the developer even know?)
In other words, the error checking the driver does to is largely ignored. Adding additional error checking at the cost of performance? That won't help at all.