pub struct Device {Show 24 fields
raw: Box<dyn DynDevice>,
pub(crate) adapter: Arc<Adapter>,
pub(crate) queue: OnceLock<Weak<Queue>>,
pub(crate) zero_buffer: ManuallyDrop<Box<dyn DynBuffer>>,
label: String,
pub(crate) command_allocator: CommandAllocator,
pub(crate) active_submission_index: AtomicFenceValue,
pub(crate) last_successful_submission_index: AtomicFenceValue,
pub(crate) fence: RwLock<ManuallyDrop<Box<dyn DynFence>>>,
pub(crate) snatchable_lock: SnatchLock,
pub(crate) valid: AtomicBool,
pub(crate) device_lost_closure: Mutex<Option<DeviceLostClosure>>,
pub(crate) trackers: Mutex<DeviceTracker>,
pub(crate) tracker_indices: TrackerIndexAllocators,
pub(crate) bgl_pool: ResourcePool<EntryMap, BindGroupLayout>,
pub(crate) alignments: Alignments,
pub(crate) limits: Limits,
pub(crate) features: Features,
pub(crate) downlevel: DownlevelCapabilities,
pub(crate) instance_flags: InstanceFlags,
pub(crate) deferred_destroy: Mutex<Vec<DeferredDestroy>>,
pub(crate) usage_scopes: Mutex<Vec<(BufferUsageScope, TextureUsageScope)>>,
pub(crate) last_acceleration_structure_build_command_index: AtomicU64,
pub(crate) indirect_validation: Option<IndirectValidation>,
}
Expand description
Structure describing a logical device. Some members are internally mutable, stored behind mutexes.
Fields§
§raw: Box<dyn DynDevice>
§adapter: Arc<Adapter>
§queue: OnceLock<Weak<Queue>>
§zero_buffer: ManuallyDrop<Box<dyn DynBuffer>>
§label: String
The label
from the descriptor used to create the resource.
command_allocator: CommandAllocator
§active_submission_index: AtomicFenceValue
The index of the last command submission that was attempted.
Note that fence
may never be signalled with this value, if the command
submission failed. If you need to wait for everything running on a
Queue
to complete, wait for last_successful_submission_index
.
last_successful_submission_index: AtomicFenceValue
The index of the last successful submission to this device’s
hal::Queue
.
Unlike active_submission_index
, which is incremented each time
submission is attempted, this is updated only when submission succeeds,
so waiting for this value won’t hang waiting for work that was never
submitted.
fence: RwLock<ManuallyDrop<Box<dyn DynFence>>>
§snatchable_lock: SnatchLock
§valid: AtomicBool
Is this device valid? Valid is closely associated with “lose the device”, which can be triggered by various methods, including at the end of device destroy, and by any GPU errors that cause us to no longer trust the state of the device. Ideally we would like to fold valid into the storage of the device itself (for example as an Error enum), but unfortunately we need to continue to be able to retrieve the device in poll_devices to determine if it can be dropped. If our internal accesses of devices were done through ref-counted references and external accesses checked for Error enums, we wouldn’t need this. For now, we need it. All the call sites where we check it are areas that should be revisited if we start using ref-counted references for internal access.
device_lost_closure: Mutex<Option<DeviceLostClosure>>
Closure to be called on “lose the device”. This is invoked directly by device.lose or by the UserCallbacks returned from maintain when the device has been destroyed and its queues are empty.
trackers: Mutex<DeviceTracker>
Stores the state of buffers and textures.
tracker_indices: TrackerIndexAllocators
§bgl_pool: ResourcePool<EntryMap, BindGroupLayout>
Pool of bind group layouts, allowing deduplication.
alignments: Alignments
§limits: Limits
§features: Features
§downlevel: DownlevelCapabilities
§instance_flags: InstanceFlags
§deferred_destroy: Mutex<Vec<DeferredDestroy>>
§usage_scopes: Mutex<Vec<(BufferUsageScope, TextureUsageScope)>>
§last_acceleration_structure_build_command_index: AtomicU64
§indirect_validation: Option<IndirectValidation>
indirect-validation
only.Implementations§
source§impl Device
impl Device
fn create_blas( self: &Arc<Self>, blas_desc: &BlasDescriptor<'_>, sizes: BlasGeometrySizeDescriptors, ) -> Result<Arc<Blas>, CreateBlasError>
fn create_tlas( self: &Arc<Self>, desc: &TlasDescriptor<'_>, ) -> Result<Arc<Tlas>, CreateTlasError>
source§impl Device
impl Device
pub(crate) fn raw(&self) -> &dyn DynDevice
pub(crate) fn require_features( &self, feature: Features, ) -> Result<(), MissingFeatures>
pub(crate) fn require_downlevel_flags( &self, flags: DownlevelFlags, ) -> Result<(), MissingDownlevelFlags>
source§impl Device
impl Device
pub(crate) fn new( raw_device: Box<dyn DynDevice>, adapter: &Arc<Adapter>, desc: &DeviceDescriptor<'_>, trace_dir_name: Option<&str>, instance_flags: InstanceFlags, ) -> Result<Self, DeviceError>
pub fn is_valid(&self) -> bool
pub fn check_is_valid(&self) -> Result<(), DeviceError>
pub fn handle_hal_error(&self, error: DeviceError) -> DeviceError
sourcepub(crate) fn deferred_resource_destruction(&self)
pub(crate) fn deferred_resource_destruction(&self)
Run some destroy operations that were deferred.
Destroying the resources requires taking a write lock on the device’s snatch lock, so a good reason for deferring resource destruction is when we don’t know for sure how risky it is to take the lock (typically, it shouldn’t be taken from the drop implementation of a reference-counted structure). The snatch lock must not be held while this function is called.
pub fn get_queue(&self) -> Option<Arc<Queue>>
pub fn set_queue(&self, queue: &Arc<Queue>)
sourcepub(crate) fn maintain<'this>(
&'this self,
fence: RwLockReadGuard<'_, ManuallyDrop<Box<dyn DynFence>>>,
poll_type: PollType<SubmissionIndex>,
snatch_guard: SnatchGuard<'_>,
) -> (UserClosures, Result<PollStatus, WaitIdleError>)
pub(crate) fn maintain<'this>( &'this self, fence: RwLockReadGuard<'_, ManuallyDrop<Box<dyn DynFence>>>, poll_type: PollType<SubmissionIndex>, snatch_guard: SnatchGuard<'_>, ) -> (UserClosures, Result<PollStatus, WaitIdleError>)
Check the current status of the GPU and process any submissions that have finished.
The poll_type
argument tells if this function should wait for a particular
submission index to complete, or if it should just poll the current status.
This will process all completed submissions, even if the caller only asked us to poll to a given submission index.
Return a pair (closures, result)
, where:
-
closures
is a list of callbacks that need to be invoked informing the user about various things occurring. These happen and should be handled even if this function returns an error, hence they are outside of the result. -
results
is a boolean indicating the result of the wait operation, including if there was a timeout or a validation error.
pub(crate) fn create_buffer( self: &Arc<Self>, desc: &BufferDescriptor<'_>, ) -> Result<Arc<Buffer>, CreateBufferError>
pub(crate) fn create_texture_from_hal( self: &Arc<Self>, hal_texture: Box<dyn DynTexture>, desc: &TextureDescriptor<'_>, ) -> Result<Arc<Texture>, CreateTextureError>
pub(crate) fn create_buffer_from_hal( self: &Arc<Self>, hal_buffer: Box<dyn DynBuffer>, desc: &BufferDescriptor<'_>, ) -> (Fallible<Buffer>, Option<CreateBufferError>)
fn create_indirect_validation_bind_group( &self, raw_buffer: &dyn DynBuffer, buffer_size: u64, usage: BufferUsages, ) -> Result<Snatchable<Box<dyn DynBindGroup>>, CreateBufferError>
indirect-validation
only.pub(crate) fn create_texture( self: &Arc<Self>, desc: &TextureDescriptor<'_>, ) -> Result<Arc<Texture>, CreateTextureError>
pub(crate) fn create_texture_view( self: &Arc<Self>, texture: &Arc<Texture>, desc: &TextureViewDescriptor<'_>, ) -> Result<Arc<TextureView>, CreateTextureViewError>
pub(crate) fn create_sampler( self: &Arc<Self>, desc: &SamplerDescriptor<'_>, ) -> Result<Arc<Sampler>, CreateSamplerError>
pub(crate) fn create_shader_module<'a>( self: &Arc<Self>, desc: &ShaderModuleDescriptor<'a>, source: ShaderModuleSource<'a>, ) -> Result<Arc<ShaderModule>, CreateShaderModuleError>
pub(crate) unsafe fn create_shader_module_spirv<'a>( self: &Arc<Self>, desc: &ShaderModuleDescriptor<'a>, source: &'a [u32], ) -> Result<Arc<ShaderModule>, CreateShaderModuleError>
pub(crate) fn create_command_encoder( self: &Arc<Self>, label: &Label<'_>, ) -> Result<Arc<CommandBuffer>, DeviceError>
sourcefn make_late_sized_buffer_groups(
shader_binding_sizes: &HashMap<ResourceBinding, BufferSize, BuildHasherDefault<FxHasher>>,
layout: &PipelineLayout,
) -> ArrayVec<LateSizedBufferGroup, { hal::MAX_BIND_GROUPS }>
fn make_late_sized_buffer_groups( shader_binding_sizes: &HashMap<ResourceBinding, BufferSize, BuildHasherDefault<FxHasher>>, layout: &PipelineLayout, ) -> ArrayVec<LateSizedBufferGroup, { hal::MAX_BIND_GROUPS }>
Generate information about late-validated buffer bindings for pipelines.
pub(crate) fn create_bind_group_layout( self: &Arc<Self>, label: &Label<'_>, entry_map: EntryMap, origin: Origin, ) -> Result<Arc<BindGroupLayout>, CreateBindGroupLayoutError>
fn create_buffer_binding<'a>( &self, bb: &'a ResolvedBufferBinding, binding: u32, decl: &BindGroupLayoutEntry, used_buffer_ranges: &mut Vec<BufferInitTrackerAction>, dynamic_binding_info: &mut Vec<BindGroupDynamicBindingData>, late_buffer_binding_sizes: &mut HashMap<u32, BufferSize, BuildHasherDefault<FxHasher>>, used: &mut BindGroupStates, snatch_guard: &'a SnatchGuard<'a>, ) -> Result<BufferBinding<'a, dyn DynBuffer>, CreateBindGroupError>
fn create_sampler_binding<'a>( &self, used: &mut BindGroupStates, binding: u32, decl: &BindGroupLayoutEntry, sampler: &'a Arc<Sampler>, ) -> Result<&'a dyn DynSampler, CreateBindGroupError>
fn create_texture_binding<'a>( &self, binding: u32, decl: &BindGroupLayoutEntry, view: &'a Arc<TextureView>, used: &mut BindGroupStates, used_texture_ranges: &mut Vec<TextureInitTrackerAction>, snatch_guard: &'a SnatchGuard<'a>, ) -> Result<TextureBinding<'a, dyn DynTextureView>, CreateBindGroupError>
fn create_tlas_binding<'a>( self: &Arc<Self>, used: &mut BindGroupStates, binding: u32, decl: &BindGroupLayoutEntry, tlas: &'a Arc<Tlas>, snatch_guard: &'a SnatchGuard<'a>, ) -> Result<&'a dyn DynAccelerationStructure, CreateBindGroupError>
pub(crate) fn create_bind_group( self: &Arc<Self>, desc: ResolvedBindGroupDescriptor<'_>, ) -> Result<Arc<BindGroup>, CreateBindGroupError>
fn check_array_binding( features: Features, count: Option<NonZeroU32>, num_bindings: usize, ) -> Result<(), CreateBindGroupError>
fn texture_use_parameters( &self, binding: u32, decl: &BindGroupLayoutEntry, view: &TextureView, expected: &'static str, ) -> Result<TextureUses, CreateBindGroupError>
pub(crate) fn create_pipeline_layout( self: &Arc<Self>, desc: &ResolvedPipelineLayoutDescriptor<'_>, ) -> Result<Arc<PipelineLayout>, CreatePipelineLayoutError>
pub(crate) fn derive_pipeline_layout( self: &Arc<Self>, derived_group_layouts: Box<ArrayVec<EntryMap, { hal::MAX_BIND_GROUPS }>>, ) -> Result<Arc<PipelineLayout>, ImplicitLayoutError>
pub(crate) fn create_compute_pipeline( self: &Arc<Self>, desc: ResolvedComputePipelineDescriptor<'_>, ) -> Result<Arc<ComputePipeline>, CreateComputePipelineError>
pub(crate) fn create_render_pipeline( self: &Arc<Self>, desc: ResolvedRenderPipelineDescriptor<'_>, ) -> Result<Arc<RenderPipeline>, CreateRenderPipelineError>
sourcepub unsafe fn create_pipeline_cache(
self: &Arc<Self>,
desc: &PipelineCacheDescriptor<'_>,
) -> Result<Arc<PipelineCache>, CreatePipelineCacheError>
pub unsafe fn create_pipeline_cache( self: &Arc<Self>, desc: &PipelineCacheDescriptor<'_>, ) -> Result<Arc<PipelineCache>, CreatePipelineCacheError>
§Safety
The data
field on desc
must have previously been returned from crate::global::Global::pipeline_cache_get_data
fn get_texture_format_features( &self, format: TextureFormat, ) -> TextureFormatFeatures
fn describe_format_features( &self, format: TextureFormat, ) -> Result<TextureFormatFeatures, MissingFeatures>
pub(crate) fn wait_for_submit( &self, submission_index: SubmissionIndex, ) -> Result<(), DeviceError>
replay
only.