Hi ! I am a Vulkan newbie, I tried to find some information about the purpose of having dispatchable and non-dispatchable handles. I read Vulkan fundamentals part about Vulkan object model but I’m quite not sure :
- On what is the purpose to have these two types of handles ? Why not having only opaque pointers ?
- On how they are handled differently by the Vulkan API ? I’m sorry if the question is too broad or not precise, but I’m struggling to understand how vulkan will typically ‘process’ a dispatchable/non-dispatchable handle when I call some fonction.
- For non-dispatchable handles, I saw that some information are encoded in the handle variable itself. Are there some examples of encoded information that could help me understand why it is done ?
The real functional difference between the two is that dispatchable handles include function dispatch logic. When you call a Vulkan function, the first parameter is the object that this function manipulates or acts on. But because different instances and devices are talking to different backends and can have different enabled extensions, the function will often need to be mapped to the correct implementation-dependent function.
Dispatchable handles are types that do this kind of call dispatching logic. There actually aren’t that many dispatchable handle types. But you may notice that the first parameter of almost every Vulkan function is a dispatchable handle of some kind: instance, device, queue, or command buffer.
But ultimately, this isn’t important to most Vulkan users. The main take-home point about non-dispatchable handles is that you cannot use equality testing of the handle value to know whether two handles are different. That is, allocating an object with a non-dispatchable handle type may return a handle that already exists, and deallocating it therefore may not destroy the object until all allocated handles referencing the same object have been destroyed.
For non-dispatchable handles, I saw that some information are encoded in the handle variable itself. Are there some examples of encoded information that could help me understand why it is done ?
This is pretty rare for handles to do, but it is theoretically possible for a VkSampler
to encode some of its information within the bits of the handle itself. Outside of the floating-point data, VkSampler
is basically just a bunch of small enums. You could fit much of that into 64-bits.
Now, do implementations do that? I don’t know, but it doesn’t really matter to users. What matters is that you cannot assume that creating a sampler will create a new unique handle value. That’s the main takeaway.
Thank you very much for your answer, it’s a lot clearer !
Just one last point I am not sure about : when you say that devices are talking to different backends, does that mean that the definition of a dispatchable handle like a VkDevice is backend dependent ?
What do you mean by “definition of a dispatchable handle”? It’s an opaque pointer; what it points to and the internal data structures are whatever the implementation needs them to be.
Sorry for the misunderstanding, I was not really aware of the typical use of opaque pointers, and how their actual implementation is chosen. But I read about how the FILE
opaque pointer is implemented in Linux (link) and that made it a lot clearer =). Thanks for the help!