-
Notifications
You must be signed in to change notification settings - Fork 497
Description
Hi, Ash (Vulkan bindings for Rust) maintainer here 👋
I recently landed a wrapper for VK_NV_low_latency2
in our bindings, and have just been made aware of a flaw in these bindings.
As it turns out the length for VkGetLatencyMarkerInfoNV::pTimings
is encoded in the pTimingCount
parameter of vkGetLatencyTimingsNV
, rather than in the struct. This results in the following disadvantages (especially annoying considering our generator):
- the
pTimings
pointer has no annotation of being an array (nor where to find the length); - The
VkGetLatencyMarkerInfoNV
is not self-descriptive about its contents; - Specifically for our generator this means we assume
pTimings
is a pointer to a single object, not an array; - A "useless/empty"
pLatencyMarkerInfo
has to be passed (it haspNext
, more on that later) just to query the length: normally this parameter isNULL
; - Upon querying a known-length array of
VkLatencyTimingsFrameReportNV
, the caller must also initialize those structs as they also have ansType
/pNext
.
Now in this Vulkan wrapper I'd typically create a stack-local VkGetLatencyMarkerInfoNV
, pass that into the Vulkan function twice, and return the user an array of VkLatencyTimingsFrameReportNV
. However, because VkGetLatencyMarkerInfoNV
is extendible via pNext
, we must expose this to the user by allowing them to set the pNext
pointer.
The same applies to VkLatencyTimingsFrameReportNV
: because the user could extend these structs as well, we need to let them provide an array of them with pNext
set so that they can optionally query additional information if there ever is an extension to this struct.
What do I expect out of this?
Since the extension has been released the API is set in stone and can no longer be changed. The issues highlighted above do not necessitate new functions to improve the experience, but I do want to bring awareness to this design, and ask a few questions about them so that I can better design my API wrappers if this is an intended pattern (used more often going forward).
Solve the count problem
I believe that the count
member could have been moved into VkGetLatencyMarkerInfoNV
, so that vk.xml
can reference this as the source for array length, and so that the struct becomes self-descriptive. If we pass a mutable pointer to VkGetLatencyMarkerInfoNV
into vkGetLatencyTimingsNV
(when pTimings = NULL
), that call could update the count member to the right size?
Alternatively the pTimings
member could have been a direct argument of vkGetLatencyTimingsNV
, obviating the need for struct VkGetLatencyMarkerInfoNV
altogether?
Use of pNext
Probably tying into the second alternative above: it seems both structs were designed with extensibility in mind, but this does bloat the interface. Was it necessary to have pNext
on both VkGetLatencyMarkerInfoNV
and VkLatencyTimingsFrameReportNV
? Not having it on the former allows us to flatten the arguments into the function.