I wonder why there’s no low level graphics api like Vulkan or D3D12 before 2010 or even at the beginning of gpu era? Why is it?Is it because gpus in the old days were not really programmable?
The only low level graphics api you would find at the time would be for the game consoles and details for those are behind NDAs.
Khronos tried to create a lower level opengl at the time.
Around the time 3.0 was being planned (2007) there were plans for big changes to opengl and breaking backwards compatibility for new features. This ultimately fell through (rumor has it that the CAD developers are to blame for that) and the deprecation model as we know it today came to be. However opengl stayed a single-threaded immediate-mode-like api with per-context state and very flaky support for shared contexts.
I.O.W. they tried but failed back in 2008 and were most likely scared to try again after all the backlash they got for it.
“Low-level” is in the eye of the beholder. Direct3D pre-12 and OpenGL (which I will refer to henceforth as “immediate APIs”) were sufficiently low-level to be effective. Every API is designed to be efficient for a particular set of system architectures. And immediate APIs were efficient enough to get by for a while.
That’s not to say that individuals didn’t rail against the inefficiencies of these APIs. John Carmack famously made a post decrying those APIs as needing a serious overhaul. But a few individuals calling for something doesn’t get that something done.
There’s a lot of work involved in creating a fundamentally different kind of API. Because of that, you would only do that work if the need is sufficiently great. And in 2010, while some individuals called for a “lower level” API, this “need” wasn’t sufficiently great to get anything done. And that is even more true “at the beginning of the gpu era”. The immediate APIs were good enough to get the necessary performance out of the systems of their era.
See, the principle problem with immediate APIs, the one that command buffer APIs are intended to solve, is that they make it essentially impossible for the CPU to thread the building of GPU commands. But that’s only a problem in a world where CPUs have lots of threads that would otherwise be sitting idle.
And that’s not the way it has always been.
Before Intel hit the power wall, CPUs got faster by doing stuff faster in one thread. Once CPU designers did hit that wall, the only way to make them significantly faster was to add more threads. Now if you only have 2 hardware threads, immediate rendering APIs wouldn’t be a problem. You could run your rendering on one thread and non-rendering tasks on another. It’s only when CPUs have 3+ threads that you would gain something from threading your rendering.
That switch-over from faster single-threaded CPU performance to higher thread count is the primary reason why immediate APIs were no longer “good enough”. And once that happened, the need for command buffer APIs became sufficiently great to force a paradigm shift.
So basically, command buffer APIs didn’t happen because of GPU changes; they came to exist because of CPU changes.
But of course, command buffer APIs are lower-level than immediate APIs. There are two reasons for this: command-buffer architectures need lower-level structures in order to be efficient. And the other reason is… it’s easier to fix something when you’re building a new thing from scratch than to make a change to an existing structure.
Explicit synchronization is an example of the former. While you could have a command buffer API with implicit syncs, it would impose a serious performance penalty at queue submission time, as a lot of time has to be spent reading through the command buffer and inserting synchronizations as needed. The same goes for image layouts.
The memory architecture is an example of a “while we’re making a new API” kind of thing. You could imagine Vulkan going with a more OpenGL-style of memory architecture (see Metal for an example). But why bother? If you’re making a new API, you’re free to go with whatever you want. And if users want a lower-level approach to memory, something more explicit than the opaque buffers and textures of old, then you may as well give it to them.
- Updated - - -
To be completely fair, OpenGL Longs Peak would have been an immediate-style of API, just like D3D of the time. So Vulkan would still have needed to exist. The principle goal of the Longs Peak effort was to make OpenGL’s API not be terrible and inefficient for an immediate rendering API.
OpenGL eventually got 90% of the Longs Peak changes, though it took GL 4.5 until it was really done.
thank you ratchet freak and Alfonse Reinheart for the detailed answer
IIRC Direct3D v3 used low level command buffers, but developers hated them. So they were removed.