use arrayvec::ArrayVec; use smallvec::SmallVec; use thiserror::Error; use wgt::{
error::{ErrorType, WebGpuError},
BufferAddress, DeviceLostReason, TextureFormat,
};
pubconst SHADER_STAGE_COUNT: usize = hal::MAX_CONCURRENT_SHADER_STAGES; // Should be large enough for the largest possible texture row. This // value is enough for a 16k texture with float4 format. pub(crate) const ZERO_BUFFER_SIZE: BufferAddress = 512 << 10;
pub(crate) const ENTRYPOINT_FAILURE_ERROR: &str = "The given EntryPoint is Invalid";
fn fire(self) { // Note: this logic is specifically moved out of `handle_mapping()` in order to // have nothing locked by the time we execute users callback code.
// Mappings _must_ be fired before submissions, as the spec requires all mapping callbacks that are registered before // a on_submitted_work_done callback to be fired before the on_submitted_work_done callback. for (mut operation, status) inself.mappings { iflet Some(callback) = operation.callback.take() {
callback(status);
}
} for (mut operation, status) inself.blas_compact_ready { iflet Some(callback) = operation.take() {
callback(status);
}
} for closure inself.submissions {
closure();
} for invocation inself.device_lost_invocations {
(invocation.closure)(invocation.reason, invocation.message);
}
}
}
assert_eq!(offset % wgt::COPY_BUFFER_ALIGNMENT, 0);
assert_eq!(size % wgt::COPY_BUFFER_ALIGNMENT, 0); // Zero out uninitialized parts of the mapping. (Spec dictates all resources // behave as if they were initialized with zero) // // If this is a read mapping, ideally we would use a `clear_buffer` command // before reading the data from GPU (i.e. `invalidate_range`). However, this // would require us to kick off and wait for a command buffer or piggy back // on an existing one (the later is likely the only worthwhile option). As // reading uninitialized memory isn't a particular important path to // support, we instead just initialize the memory here and make sure it is // GPU visible, so this happens at max only once for every buffer region. // // If this is a write mapping zeroing out the memory here is the only // reasonable way as all data is pushed to GPU anyways.
let mapped = unsafe { core::slice::from_raw_parts_mut(mapping.ptr.as_ptr(), size as usize) };
// We can't call flush_mapped_ranges in this case, so we can't drain the uninitialized ranges either if !mapping.is_coherent
&& kind == HostMap::Read
&& !buffer.usage.contains(wgt::BufferUsages::MAP_WRITE)
{ for uninitialized in buffer
.initialization_status
.write()
.uninitialized(offset..(size + offset))
{ // The mapping's pointer is already offset, however we track the // uninitialized range relative to the buffer's start. let fill_range =
(uninitialized.start - offset) as usize..(uninitialized.end - offset) as usize;
mapped[fill_range].fill(0);
}
} else { for uninitialized in buffer
.initialization_status
.write()
.drain(offset..(size + offset))
{ // The mapping's pointer is already offset, however we track the // uninitialized range relative to the buffer's start. let fill_range =
(uninitialized.start - offset) as usize..(uninitialized.end - offset) as usize;
mapped[fill_range].fill(0);
// NOTE: This is only possible when MAPPABLE_PRIMARY_BUFFERS is enabled. if !mapping.is_coherent
&& kind == HostMap::Read
&& buffer.usage.contains(wgt::BufferUsages::MAP_WRITE)
{ unsafe { raw_device.flush_mapped_ranges(raw_buffer, &[uninitialized]) };
}
}
}
impl DeviceError { /// Only use this function in contexts where there is no `Device`. /// /// Use [`Device::handle_hal_error`] otherwise. pubfn from_hal(error: hal::DeviceError) -> Self { match error {
hal::DeviceError::Lost => Self::Lost,
hal::DeviceError::OutOfMemory => Self::OutOfMemory,
hal::DeviceError::Unexpected => Self::Lost,
}
}
}
#[derive(Clone, Debug, Error)] #[error("Features {0:?} are required but not enabled on the device")] pubstruct MissingFeatures(pub wgt::Features);
#[derive(Clone, Debug, Error)] #[error( "Downlevel flags {0:?} are required but not supported on the device.\n{DOWNLEVEL_ERROR_MESSAGE}",
)] pubstruct MissingDownlevelFlags(pub wgt::DownlevelFlags);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.