Skip to content

_from_raw and _from_hal APIs bypass validation, so wgpu should offer validated alternatives #9980

Description

@jimblandy

We've been seeing a number of bugs caused by incorrect use of foo_from_raw APIs, which construct a higher-level resource from a lower-level resource. I'm referring to APIs like these:

There are similar functions for other sorts of resources like buffers and textures. The names vary, but I'm going to collectively call all of these _from_raw functions.

These _from_raw functions have legitimate uses, and sometimes there may not be any practical alternative. For example, if one wishes to use wgpu to manage resources created by some other part of the system, the _from_raw pattern seems like your only option.

However, in many cases, people are forced to use _from_raw functions for resources they've just created themselves, simply because they need to pass the creation operation some information specific to the particular backend they're using. But in doing so, they bypass the validation that would normally be carried out by wgpu-core. In this way, the present API design creates pressure on users to skip the validation that is one of wgpu's selling points. (Ideally, there would be a cross-platform wgpu-core feature for their case, but designing and implementing such a thing may not always be feasible.)

One solution is to let the users invoke the validation explicitly themselves, as is done in #9979.

Another solution we might consider is inspired by Vulkan's extending structures, but uses standard Rust features to do this in a type-safe way. Here, users would continue to call wgpu_core methods for resource creation as usual. However, these methods would accept a Vec<Box<dyn Any>> (empty in the normal case) which they would pass through unexamined to wgpu_hal. The wgpu_hal backend would then downcast the vector's elements to specific types it recognizes, and use them to inform resource creation. If an element had an unrecognized type, the backend would panic.

This effectively allows wgpu_core functions, which are backend-independent, to accept backend-specific types. Users would exercise exactly the same wgpu-core code paths as normal resource creation. I've verified that it's even possible to pass extending types by value, so that the user can transfer ownership of resources through wgpu-core to wgpu-hal. No unsafe code is required.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions