-
Notifications
You must be signed in to change notification settings - Fork 547
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
Mark most functions as unsafe #2453
Comments
Thank you for filing the issue! It did raise up quite a few times, and it's super important to discuss in detail. The initial approach of not having
|
FWIW, gleam lying about unsafety has been criticized by |
Many of those methods should actually have been marked unsafe, I'm fixing them when I stumble upon such methods.
It's a bit more complicated than that, for example new unpack parameters could be introduced in such a way that tweaking them makes your safe |
One approach that may work for gfx-hal is to use the same strategy as the |
@fintelia this is an interesting idea, but I'm not sure if it's valid. The point of summoning @gankro as our unsafety expert :) |
There's definitely some precedent for rules-lawyering unsafe boundaries. The key invariant that the stdlib team has generally focused on is: if you don't write This gives us a fair amount of leeway to only mark key operations as unsafe, and mark many others as safe, with the understanding that you need to use one of those key unsafe operations to trigger unsafety. For instance casting pointers to different types, or making them from integers is considered safe, because all the other operations like With that said, I can't think of an example where we made this kind of "blood pact" design, where you sign away your rights by calling unsafe once upfront, and then never need to state that you understand things are unsafe again (at least for public APIs -- we lie about unsafety internally in the stdlib all the time since it doesn't matter). I think the reason we don't tend to do that is it makes it easy for someone to "sign the pact for you" -- imagine a version of the |
As a rule of thumb I think that any function that can be used to violate Rust safety guarantees must be marked unsafe. E.g. if you can provide a set of valid usage rules for the function - mark function unsafe and specify rules in doc comment. Only if the is no rules to follow the function can be considered safe. |
This crate provides low level access to an extremely powerful, programmable co-processor with direct DMA access to main memory. It relies on underlying APIs which deliberately leave certain misuses undefined because detecting them would incur too large of a runtime cost. I agree that the ideal option would be to identify a small subset of the gfx-hal functions that are unsafe and mark everything else safe, but I'm not convinced that there is a small subset that would qualify. As I see it there are a couple options:
In cases 2-4 the "set of valid usage rules" will probably just be a pointer to the vulkan spec and a disclaimer not to do anything that would cause problems, perhaps with a specific warnings about avoiding use after frees, etc. |
This quote actually got me thinking... What is the real unsafety limits of command buffer recording? All the work during recording is done on CPU, and the basic constraints (say, resources are alive at least at the point of recording) are easy to check in the backends. What if we proceed with the following guidelines:
|
This one looks similar to One could make the crate panic if the Disclaimer: I know nothing about Vulkan. |
@nox if we are willing to do extensive checks sacrificing performance like OpenGL does - we would use OpenGL 😄 Take note that robust buffer access doesn't guard you against other usage violation. |
How is that related? Whichever group will expose Vulkan to the Web will have to implement those extensive checks too. It's not about the tech but about where it's exposed. The Web runs third-party code so the API to access OpenGL needed safety checks, that's all. My solution didn't say anything about implementing extensive checks in this crate. |
@nox So. Should be |
If there is something that leads to out-of-bounds buffer access, yes, that thing should definitely be unsafe. My point was that the |
Don't edit your comments, I almost missed that. I am aware this doesn't guard against other usage violations, this kind of safety study is on a per-basis thing. |
Also |
My worst habit. |
My point is that command buffer recording methods has complex rules for valid usage. The idea to mark them all safe seems weird to me. |
I think of it as Draw() being an analogy of taking a pointer from a reference (no real unsafe work done yet), and Submit() being the pointer dereference.
… On Nov 2, 2018, at 07:18, Zakarum ***@***.***> wrote:
My point is that command buffer recording methods has complex rules for valid usage. The idea to mark them all safe seems weird to me.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
|
@kvark can you be sure about that? |
I expect |
I don't expect so, or the specification would have to mention that these resources (at least the mutable ones) be externally synchronized in the list at section 2.6 of this page: https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html. |
@nical Those resources are immutable. You don't need to externally synchronize them if there is no way to mutate them. |
It may be don't read them until submission. But it would make sense to do CPU side job while recording since recording can be done in parallel. Deferring computations until submission will reduce CPU utilization. |
@omni-viral I checked the AMD's Vulkan implementation, and this indeed appears to be the case: https://github.com/mesa3d/mesa/blob/677b496b6bd07cbe05dd429344ba525619cdd08c/src/amd/vulkan/radv_cmd_buffer.c#L1843 The driver checks the pipeline, active descriptor sets, vertex buffers, and more - all on the draw(). |
Perhaps we should make all the draws, dispatches, and copies unsafe then. It's still a big win if all the state setting is "safe" prior to the draws. |
@kvark I'd stick with Vulkan valid usage rules. Without making assumptions about how spec is implemented. If there is enough data to assert valid usage (without compromising speed) then do that and mark function safe. |
@omni-viral there is a certain trade-off we can afford by adding (limited!) run-time checks, e.g. vkCmdBindPipeline valid usage is trivial to check with an |
Unfortunately there aren't many you can check that easily. |
Because we follow Vulkan closely for the HAL API, we don't have many safety guarantees for most of the API usage. A few users have asked to have the explicit unsafe annotation to make it more obvious that no guarantees are provided here.
The text was updated successfully, but these errors were encountered: