Hi! I’m writing 3d engine using OpenGL but with perspective adding support of Vulkan later. Now I’m writing a wrapper for Vertex Array Object and bumped into a problem that in Vulkan there is no similar functionality. I found that VkCommandBuffer is something similar to the Vertex Array Object, but much wider and with more features. So how do I best implement a wrapper for VAO so that later I can add Vulkan support without problems (and without cutting back on Vulkan’s capabilities)?
Command buffers have nothing to do with VAOs or anything like them. They’re sequences of arbitrary commands, while VAOs store a very narrow set of state (most of which should not be changed).
Vulkan has no concept equivalent to a VAO. The format data of a VAO is part of the pipeline object, and that is of course linked to pretty much everything else in the pipeline: shaders, blend parameters, etc. So the vertex format information is not something which is separate and distinct from other stuff the way it is in OpenGL.
If you want to write an OpenGL engine that is forward-looking to Vulkan, then write it like you would for Vulkan. That is, don’t have VAOs or modifiable vertex formats at all. Your conceptual abstraction should treat vertex formats, the program pipeline object, blend state, and the rest all as a single, largely immutable, construct. Just like Vulkan does.
Will performance be affected if each frame is called multiple glEnableVertexAttribArray, glBindBuffer and glVertexAttribPointer?
It turns out that in my case it is better to create my likeness of CommandBuffer and work with it, rather than with OpenGL-like calls?
I’m afraid that in this case, I will get a little overhead…
If your goal is to be like Vulkan, why would you be using APIs that aren’t anything remotely like what exists in Vulkan and thus wouldn’t easily transfer over? You should be using direct state access APIs and separate attribute format VAOs, as those map more effectively to what Vulkan is doing. And when you do that, there’s no need for changing the vertex format at all, thus directly mirroring how Vulkan works.
Your abstraction should not just be transparent wrappers around OpenGL functions; that should never have even been on the table. What exactly that system looks like is up to you, but I don’t see any particular reason why it would need to look like a command buffer. CBs are how you render, not how you store data and manage for rendering. Obviously for performance reasons, how data gets stored and managed is something that needs to be taken into account with regard to how you render. But the specific nature of CBs is not something that needs to live in your object management structures.
I need to support old devices that don’t support the Vulkan, and even some new versions of OpenGL.
As I wrote above, in the future I want to use Vulkan without cutting back on its capabilities. That is why, for now, I only see an “emulation” of this command buffer for OpenGL… I can’t use Vulkan without CBs, right?
Hardware that doesn’t support OpenGL 4.5+, broadly speaking, also probably isn’t still being supported with drivers. Which means that driver bugs will likely never get fixed.
It’s best to avoid trying to support such hardware to begin with. But if you feel like you have to, then do what you have to do.
That misses my point. This discussion is talking about VAOs. The Vulkan analog to VAOs is not a command buffer. So there’s no purpose in, as you put it, “create my likeness of CommandBuffer and work with it” as it relates to the concepts surrounding vertex formats, buffers, and the like. So your statement makes about as much sense as saying that you will “create my likeness of a texture and work with it” within the context of this discussion.
So again, I don’t see any particular reason why a VAO abstraction would need to look like a command buffer.