-
Notifications
You must be signed in to change notification settings - Fork 187
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
Allow building Entry
/Instance
/Device
from handle+fns
#748
Conversation
Another wrapper will have its own function pointer table structs, and converting those to ash's would be incredibly tedious and fragile. Why not just let ash re-load the function pointers as usual? |
Vulkano uses ash under the hood and therefore the same function pointer table structs. I don't know if there are other examples. Loading twice would obviously work but doesn't seem like it should be the only choice to me. |
Then Vulkano has |
They don't want to use ash::Device because they don't like that it takes slices from what I understand. EDIT: I misunderstood what you meant, so you say they should use ash::Device and then use the function pointers from it. I suppose this is feasible. But either way I was just providing an use case. I think adding this constructor just makes ash more versatile. |
Also the request for this functionality is not coming from them, it's coming from me, I need to use both crates because vulkano is removing some unsafe wrappers which I use. Thinking this is something one might generally be interested in doing and also something that doesn't add maintenance burden I opened this PR. |
To put it another way, it seems like it makes sense that loading the driver shouldn't be the only way of using the wrappers. |
Not liking the high level wrappers does not preclude using
It has significant upsides. For example, it does not force you to use the same version of ash as Vulkano. That said, so long as we expose |
Thoughts:
|
As suggested I added an analogous constructor to |
Hmm, one other consideration: these might force semver breakage when we support new minor versions of Vulkan. Do we otherwise necessarily break on such updates? If not, that makes this more costly. We could mitigate that by having a separate constructor for every minor version, in which case this should probably be renamed, though that feels rather ugly. |
That's a good point, so would it be sufficient if I appended |
I think that solves the problem. I'm interested in @MarijnS95's thoughts on this too.
Let's not; we can always add them in the future. It could confuse users targeting earlier Vulkan versions, but it's an obscure enough interface that I'm not too bothered. |
Vulkano doesn't use I was under the impression that Vulkano might not expose their internals nor Perhaps we could ask @Rua to replace Sure, we could provide this helper to be more lenient in how ash high-level wrappers are put together and used. After all, a user could pass a custom loader function with a massive If you want to be consistent and provide it for Then the semver-breakage: this is tricky. We cannot easily version the function as all fields must be initialized (they are not
Alternatively we can preemptively make this function return an @Ralith what's your opinion on the |
I think
That's what I had in mind, though I don't know if it's useful to deprecate older ones, since they'll continue to be reasonable to use when targeting older versions. Deprecating does let us remove them when we break for other reasons, which might be nice to limit growth, though I'm not sure if Vulkan is going to get that many minor versions, and we can always deprecate in the future. |
Added a |
I'd |
Entry
/Instance
/Device
from handle+fns
Thanks @pac85. Looks like a few things remain before this is ready:
|
Np! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, thanks! I've been wondering if it makes sense to let e.g. Entry::from_static_fn()
use the new function, but other than that I'll merge and backport this shortly.
I generally try to (but not always) stick to a single commit, especially if all the messages would be the same, since it gets squash-merged in the end. Having a separate commit per entry/instance/device doesn't really add value here. But don't worry about squashing them, I can fix that up very easily while applying. Sorry for the conflicts, we just removed a bunch of fields (with empty structs) in #752 :) |
Adds a constructor to build a device from a handle + functions. Helps with interoperability with other vulkan wrappers
Adds a constructor to build an instance from a handle + functions. Helps with interoperability with other vulkan wrappers
Now constructors use the |
Thanks, looks like it still wouldn't compile though, but let me allow the CI workflow to be sure. |
compilation fixed now |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Adds a constructor to build an entry from a handle + functions. Helps with interoperability with other vulkan wrappers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, looks like we're all set!
Fantastic! Thanks everyone! |
`Entry` is the only struct marking some Vulkan API calls as safe, as their soundness can be trivially upheld. This however relies on `vkGetInstanceProcAddr` returning a sound function pointer, which is not something we can guarantee when the user passes us function pointers via `Entry::from_parts_1_1()` instead: hence mark this new constructor as `unsafe` to uphold this contract. Related discussion chain: #748 (comment)
We don't mark any of the extern calls to Vulkan function-pointers safe except for a few `Entry` functions. Their safety contract was easy to validate, but now that we exposed a constructor function to let the user provide function pointers in the form of `Entry::from_parts_1_1()` it is no longer safe to assume that we are calling the function that adheres to the contract specified in the Vulkan reference. Because we don't rigorously do this validation and safe-marking anywhere else either, mark these function calls as `unsafe`. Related discussion chain: #748 (comment)
We don't mark any of the extern calls to Vulkan function-pointers safe except for a few `Entry` functions. Their safety contract was easy to validate, but now that we exposed a constructor function to let the user provide function pointers in the form of `Entry::from_parts_1_1()` it is no longer safe to assume that we are calling the function that adheres to the contract specified in the Vulkan reference. Because we don't rigorously do this validation and safe-marking anywhere else either, mark these function calls as `unsafe`. Related discussion chain: #748 (comment)
We don't mark any of the extern calls to Vulkan function-pointers safe except for a few `Entry` functions. Their safety contract was easy to validate, but now that we exposed a constructor function to let the user provide function pointers in the form of `Entry::from_parts_1_1()` it is no longer safe to assume that we are calling the function that adheres to the contract specified in the Vulkan reference. Because we don't rigorously do this validation and safe-marking anywhere else either, mark these function calls as `unsafe`. Related discussion chain: #748 (comment)
Adds a constructor to build a device from a handle + functions.
Helps with interoperability with other vulkan wrappers where the user might have loaded the functions already.