-
Notifications
You must be signed in to change notification settings - Fork 438
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: use non_exhaustive
(instead of builders) for all extendable Vulkan structs
#1808
Comments
Can you show an example of how e.g. ComputePipeline's builder will look like? |
Something like this: ComputePipeline::start(device)
.shader(cs.entry_point("main").unwrap())
.layout(layout) // would be optional, defaults to a layout generated from the shader
.build().unwrap() So it would be similar to how the |
ok, looks good! |
Yes, that sounds good! I think DeviceMemory already uses one. Feel free to change the API if you find a cleaner way to do it generically! |
An alternative design I thought of, that is a bit further from the current typical builder design but closer to Vulkan, is this version: ComputePipeline::new(
device,
ComputePipelineCreateInfo::default()
.shader(cs.entry_point("main").unwrap())
.layout(layout)
).unwrap() In this version, the "builder" only helps to gather the creation info, and is then passed to Not all extendable structures are found in object creation APIs either. Note physical_device.image_format_properties(ImageFormatInfo::default()
.format(format)
.ty(ty)
.tiling(tiling)
.usage(usage)
.flags(flags)
.external_memory_handle_type(handle_type) // from extension struct
.image_view_type(view_type) // from extension struct
) Please let me know what you think of this style, whether you think it's better than Vulkano's current builder style or if you have alternative ideas. Lastly, there's the few APIs, including the one above, where the output of a Vulkan function is an extendable struct. Builderfying a struct that's meant to be returned to the user seems awkward, it would essentially be a struct with only getter methods. We may have to look for alternative ways to make them more robust against breaking changes. |
I just discovered (perhaps way too late) that structs can be given a This seems useful for extendable structs. Constructing a device would look like this (using #1814 as a base): Device::new(
physical_device,
DeviceCreateInfo {
queues: [
QueueCreateInfo {
queues: [1.0].into(),
..QueueCreate::family(queue_family_graphics)
},
QueueCreateInfo {
queues: [0.5].into(),
..QueueCreate::family(queue_family_compute),
].into(),
enabled_extensions: physical.required_extensions().union(&device_extensions),
enabled_features: features,
..Default::default()
},
) This is not only backwards compatible thanks to the struct update syntax, but should also be more familiar to C Vulkan users. Note that thanks to the struct update syntax, you can still use sensible defaults just like you can with builders. For example, an ImageView::new(
image,
Default::default(),
) Personally I really like this style. It is rather different from current Vulkano, but I think it has some usability advantages, and uses a core Rust feature specifically introduced to avoid breaking compatibility. A big advantage is that structures can't just be written this way, but the fields from the structs can also be read, something not possible with a builder unless you give it both getters and setters (ew!). |
non_exhaustive
(instead of builders) for all extendable Vulkan structs
Interesting. This is a new thing for me too :) |
I think it would be great. Even now, we are using many getters in vulkano to access internal fields. |
One detail to note is that values with no sensible default would have to be wrapped in an |
Well, never mind that, because |
I found a workaround, and made a draft PR for #1815 using the struct update syntax instead of a builder. |
Vulkan has a neat, if somewhat cumbersome mechanism for adding new functionality to existing APIs, by means of the
pNext
pointers. The goal behind this design is to allow extending the API without breaking existing code. Preventing code breakage is also a goal for Vulkano, and one idiomatic way to do that is by using builders. You can always add new functions to a builder without breaking existing code, as long as the builder behaves the same as before the new function was added.I therefore propose that, in principle, whenever Vulkan allows for extension using
pNext
, Vulkano maps this to a builder. Existing object types not currently using a builder would be converted to use one, such asInstance
,Device
,UnsafeBuffer
,ComputePipeline
and others.The text was updated successfully, but these errors were encountered: