Skip to content

Commit

Permalink
[hal] Document resource destruction methods, and a few other things.
Browse files Browse the repository at this point in the history
Document some more safety expectations for
- resource destruction methods
- `CommandEncoder` methods
- `Queue::submit`

Document `Fence` creation a bit.

Document the `Queue` trait a bit.

Document `vulkan` shader module handling a bit.
  • Loading branch information
jimblandy committed May 23, 2024
1 parent b898cdf commit c92968e
Showing 1 changed file with 86 additions and 9 deletions.
95 changes: 86 additions & 9 deletions wgpu-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,70 @@ pub trait Adapter: WasmNotSendSync {
unsafe fn get_presentation_timestamp(&self) -> wgt::PresentationTimestamp;
}

/// A connection to a GPU and a pool of resources to use with it.
///
/// A `wgpu-hal` `Device` represents an open connection to a specific graphics
/// processor, controlled via the backend [`Device::A`]. A `Device` is mostly
/// used for creating resources. Each `Device` has an associated [`Queue`] used
/// for command submission.
///
/// On Vulkan a `Device` corresponds to a logical device ([`VkDevice`]). Other
/// backends don't have an exact analog: for example, [`ID3D12Device`]s and
/// [`MTLDevice`]s are owned by the backends' [`wgpu_hal::Adapter`]
/// implementations, and shared by all [`wgpu_hal::Device`]s created from that
/// `Adapter`.
///
/// A `Device`'s life cycle is generally:
///
/// 1) Obtain a `Device` and its associated [`Queue`] by calling
/// [`Adapter::open`].
///
/// Alternatively, the backend-specific types that implement [`Adapter`] often
/// have methods for creating a `wgpu-hal` `Device` from a platform-specific
/// handle. For example, [`vulkan::Adapter::device_from_raw`] can create a
/// [`vulkan::Device`] from an [`ash::Device`].
///
/// 1) Create resources to use on the device by calling methods like
/// [`Device::create_texture`] or [`Device::create_shader_module`].
///
/// 1) Call [`Device::create_command_encoder`] to obtain a [`CommandEncoder`],
/// which you can use to build [`CommandBuffer`]s holding commands to be
/// executed on the GPU.
///
/// 1) Call [`Queue::submit`] on the `Device`'s associated [`Queue`] to submit
/// [`CommandBuffer`]s for execution on the GPU. If needed, call
/// [`Device::wait`] to wait for them to finish execution.
///
/// 1) Free resources with methods like [`Device::destroy_texture`] or
/// [`Device::destroy_shader_module`].
///
/// 1) Shut down the device by calling [`Device::exit`].
///
/// [`vkDevice`]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VkDevice
/// [`ID3D12Device`]: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/nn-d3d12-id3d12device
/// [`MTLDevice`]: https://developer.apple.com/documentation/metal/mtldevice
/// [`wgpu_hal::Adapter`]: Adapter
/// [`wgpu_hal::Device`]: Device
/// [`vulkan::Adapter::device_from_raw`]: vulkan/struct.Adapter.html#method.device_from_raw
/// [`vulkan::Device`]: vulkan/struct.Device.html
/// [`ash::Device`]: https://docs.rs/ash/latest/ash/struct.Device.html
/// [`CommandBuffer`]: Api::CommandBuffer
///
/// # Safety
///
/// As with other `wgpu-hal` APIs, [validation] is the caller's
/// responsibility. Here are the general requirements for all `Device`
/// methods:
///
/// - Any resource passed to a `Device` method must have been created by that
/// `Device`. For example, a [`Texture`] passed to [`Device::destroy_texture`] must
/// have been created with the `Device` passed as `self`.
///
/// - Resources may not be destroyed if they are used by any submitted command
/// buffers that have not yet finished execution.
///
/// [validation]: index.html#validation-is-the-calling-codes-responsibility-not-wgpu-hals
/// [`Texture`]: Api::Texture
pub trait Device: WasmNotSendSync {
type A: Api;

Expand Down Expand Up @@ -721,22 +785,35 @@ pub trait Queue: WasmNotSendSync {
/// themselves are unordered. If each thread uses a separate [`Fence`], this
/// problem does not arise.
///
/// Valid usage:
/// # Safety
///
/// - Each [`CommandBuffer`][cb] in `command_buffers` must have been created
/// from a [`CommandEncoder`][ce] that was constructed from the
/// [`Device`][d] associated with this [`Queue`].
///
/// - Each [`CommandBuffer`][cb] must remain alive until the submitted
/// commands have finished execution. Since command buffers must not
/// outlive their encoders, this implies that the encoders must remain
/// alive as well.
///
/// - All of the [`CommandBuffer`][cb]s were created from
/// [`CommandEncoder`][ce]s that are associated with this queue.
/// - All resources used by a submitted [`CommandBuffer`][cb]
/// ([`Texture`][t]s, [`BindGroup`][bg]s, [`RenderPipeline`][rp]s, and so
/// on) must remain alive until the command buffer finishes execution.
///
/// - All of those [`CommandBuffer`][cb]s must remain alive until
/// the submitted commands have finished execution. (Since
/// command buffers must not outlive their encoders, this
/// implies that the encoders must remain alive as well.)
/// - Every [`SurfaceTexture`][st] that any command in `command_buffers`
/// writes to must appear in the `surface_textures` argument.
///
/// - All of the [`SurfaceTexture`][st]s that the command buffers
/// write to appear in the `surface_textures` argument.
/// - Each [`SurfaceTexture`][st] in `surface_textures` must be configured
/// for use with the [`Device`][d] associated with this [`Queue`],
/// typically by calling [`Surface::configure`].
///
/// [`Fence`]: Api::Fence
/// [cb]: Api::CommandBuffer
/// [ce]: Api::CommandEncoder
/// [d]: Api::Device
/// [t]: Api::Texture
/// [bg]: Api::BindGroup
/// [rp]: Api::RenderPipeline
/// [st]: Api::SurfaceTexture
unsafe fn submit(
&self,
Expand Down

0 comments on commit c92968e

Please sign in to comment.