Skip to content

Commit

Permalink
feat: add AsWebGpuErrorType and ErrorType APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
ErichDonGubler committed Jan 22, 2025
1 parent 3dd925b commit 930d5dc
Show file tree
Hide file tree
Showing 18 changed files with 804 additions and 1 deletion.
99 changes: 99 additions & 0 deletions wgpu-core/src/binding_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::{
device::{
bgl, Device, DeviceError, MissingDownlevelFlags, MissingFeatures, SHADER_STAGE_COUNT,
},
error::{AsWebGpuErrorType, ErrorType},
id::{BindGroupLayoutId, BufferId, SamplerId, TextureViewId, TlasId},
init_tracker::{BufferInitTrackerAction, TextureInitTrackerAction},
pipeline::{ComputePipeline, RenderPipeline},
Expand Down Expand Up @@ -78,6 +79,22 @@ pub enum CreateBindGroupLayoutError {
InvalidVisibility(wgt::ShaderStages),
}

impl AsWebGpuErrorType for CreateBindGroupLayoutError {
fn as_webgpu_error_type(&self) -> ErrorType {
match self {
Self::Device(e) => e.as_webgpu_error_type(),

Self::ConflictBinding(_)
| Self::Entry { .. }
| Self::TooManyBindings(_)
| Self::InvalidBindingIndex { .. }
| Self::InvalidVisibility(_)
| Self::ContainsBothBindingArrayAndDynamicOffsetArray
| Self::ContainsBothBindingArrayAndUniformBuffer => ErrorType::Validation,
}
}
}

//TODO: refactor this to move out `enum BindingError`.

#[derive(Clone, Debug, Error)]
Expand Down Expand Up @@ -203,6 +220,45 @@ pub enum CreateBindGroupError {
InvalidResource(#[from] InvalidResourceError),
}

impl AsWebGpuErrorType for CreateBindGroupError {
fn as_webgpu_error_type(&self) -> ErrorType {
let e: &dyn AsWebGpuErrorType = match self {
Self::Device(e) => e,
Self::DestroyedResource(e) => e,
Self::MissingBufferUsage(e) => e,
Self::MissingTextureUsage(e) => e,
Self::ResourceUsageCompatibility(e) => e,
Self::InvalidResource(e) => e,
Self::BindingArrayPartialLengthMismatch { .. }
| Self::BindingArrayLengthMismatch { .. }
| Self::BindingArrayZeroLength
| Self::BindingRangeTooLarge { .. }
| Self::BindingSizeTooSmall { .. }
| Self::BindingsNumMismatch { .. }
| Self::BindingZeroSize(_)
| Self::DuplicateBinding(_)
| Self::MissingBindingDeclaration(_)
| Self::SingleBindingExpected
| Self::UnalignedBufferOffset(_, _, _)
| Self::BufferRangeTooLarge { .. }
| Self::WrongBindingType { .. }
| Self::InvalidTextureMultisample { .. }
| Self::InvalidTextureSampleType { .. }
| Self::InvalidTextureDimension { .. }
| Self::InvalidStorageTextureFormat { .. }
| Self::InvalidStorageTextureMipLevelCount { .. }
| Self::WrongSamplerComparison { .. }
| Self::WrongSamplerFiltering { .. }
| Self::DepthStencilAspect
| Self::StorageReadNotSupported(_)
| Self::StorageWriteNotSupported(_)
| Self::StorageReadWriteNotSupported(_)
| Self::StorageAtomicNotSupported(_) => return ErrorType::Validation,
};
e.as_webgpu_error_type()
}
}

#[derive(Clone, Debug, Error)]
pub enum BindingZone {
#[error("Stage {0:?}")]
Expand All @@ -220,6 +276,12 @@ pub struct BindingTypeMaxCountError {
pub count: u32,
}

impl AsWebGpuErrorType for BindingTypeMaxCountError {
fn as_webgpu_error_type(&self) -> ErrorType {
ErrorType::Validation
}
}

#[derive(Clone, Debug)]
pub enum BindingTypeMaxCountErrorKind {
DynamicUniformBuffers,
Expand Down Expand Up @@ -605,6 +667,22 @@ pub enum CreatePipelineLayoutError {
InvalidResource(#[from] InvalidResourceError),
}

impl AsWebGpuErrorType for CreatePipelineLayoutError {
fn as_webgpu_error_type(&self) -> ErrorType {
let e: &dyn AsWebGpuErrorType = match self {
Self::Device(e) => e,
Self::MissingFeatures(e) => e,
Self::InvalidResource(e) => e,
Self::TooManyBindings(e) => e,
Self::MisalignedPushConstantRange { .. }
| Self::MoreThanOnePushConstantRangePerStage { .. }
| Self::PushConstantRangeTooLarge { .. }
| Self::TooManyGroups { .. } => return ErrorType::Validation,
};
e.as_webgpu_error_type()
}
}

#[derive(Clone, Debug, Error)]
#[non_exhaustive]
pub enum PushConstantUploadError {
Expand Down Expand Up @@ -636,6 +714,12 @@ pub enum PushConstantUploadError {
Unaligned(u32),
}

impl AsWebGpuErrorType for PushConstantUploadError {
fn as_webgpu_error_type(&self) -> ErrorType {
ErrorType::Validation
}
}

/// Describes a pipeline layout.
///
/// A `PipelineLayoutDescriptor` can be used to create a pipeline layout.
Expand Down Expand Up @@ -883,6 +967,12 @@ pub enum BindError {
},
}

impl AsWebGpuErrorType for BindError {
fn as_webgpu_error_type(&self) -> ErrorType {
ErrorType::Validation
}
}

#[derive(Debug)]
pub struct BindGroupDynamicBindingData {
/// The index of the binding.
Expand Down Expand Up @@ -1044,6 +1134,15 @@ pub enum GetBindGroupLayoutError {
InvalidResource(#[from] InvalidResourceError),
}

impl AsWebGpuErrorType for GetBindGroupLayoutError {
fn as_webgpu_error_type(&self) -> ErrorType {
match self {
Self::InvalidGroupIndex(_) => ErrorType::Validation,
Self::InvalidResource(e) => e.as_webgpu_error_type(),
}
}
}

#[derive(Clone, Debug, Error, Eq, PartialEq)]
#[error("Buffer is bound with size {bound_size} where the shader expects {shader_size} in group[{group_index}] compact index {compact_index}")]
pub struct LateMinBufferBindingSizeMismatch {
Expand Down
25 changes: 25 additions & 0 deletions wgpu-core/src/command/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ use crate::{
AttachmentData, Device, DeviceError, MissingDownlevelFlags, RenderPassContext,
SHADER_STAGE_COUNT,
},
error::{AsWebGpuErrorType, ErrorType},
hub::Hub,
id,
init_tracker::{BufferInitTrackerAction, MemoryInitKind, TextureInitTrackerAction},
Expand Down Expand Up @@ -906,6 +907,15 @@ pub enum CreateRenderBundleError {
InvalidSampleCount(u32),
}

impl AsWebGpuErrorType for CreateRenderBundleError {
fn as_webgpu_error_type(&self) -> ErrorType {
match self {
Self::ColorAttachment(e) => e.as_webgpu_error_type(),
Self::InvalidSampleCount(_) => ErrorType::Validation,
}
}
}

/// Error type returned from `RenderBundleEncoder::new` if the sample count is invalid.
#[derive(Clone, Debug, Error)]
#[non_exhaustive]
Expand Down Expand Up @@ -1550,6 +1560,21 @@ pub struct RenderBundleError {
inner: RenderBundleErrorInner,
}

impl AsWebGpuErrorType for RenderBundleError {
fn as_webgpu_error_type(&self) -> ErrorType {
let Self { scope: _, inner } = self;
let e: &dyn AsWebGpuErrorType = match inner {
RenderBundleErrorInner::Device(e) => e,
RenderBundleErrorInner::RenderCommand(e) => e,
RenderBundleErrorInner::Draw(e) => e,
RenderBundleErrorInner::MissingDownlevelFlags(e) => e,
RenderBundleErrorInner::Bind(e) => e,
RenderBundleErrorInner::InvalidResource(e) => e,
};
e.as_webgpu_error_type()
}
}

impl RenderBundleError {
pub fn from_device_error(e: DeviceError) -> Self {
Self {
Expand Down
23 changes: 23 additions & 0 deletions wgpu-core/src/command/clear.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::{
api_log,
command::CommandEncoderError,
device::DeviceError,
error::{AsWebGpuErrorType, ErrorType},
get_lowest_common_denom,
global::Global,
id::{BufferId, CommandEncoderId, TextureId},
Expand Down Expand Up @@ -75,6 +76,28 @@ whereas subesource range specified start {subresource_base_array_layer} and coun
InvalidResource(#[from] InvalidResourceError),
}

impl AsWebGpuErrorType for ClearError {
fn as_webgpu_error_type(&self) -> ErrorType {
let e: &dyn AsWebGpuErrorType = match self {
Self::DestroyedResource(e) => e,
Self::MissingBufferUsage(e) => e,
Self::Device(e) => e,
Self::CommandEncoderError(e) => e,
Self::InvalidResource(e) => e,
Self::NoValidTextureClearMode(..)
| Self::MissingClearTextureFeature
| Self::UnalignedFillSize(..)
| Self::UnalignedBufferOffset(..)
| Self::OffsetPlusSizeExceeds64BitBounds { .. }
| Self::BufferOverrun { .. }
| Self::MissingTextureAspect { .. }
| Self::InvalidTextureLevelRange { .. }
| Self::InvalidTextureLayerRange { .. } => return ErrorType::Validation,
};
e.as_webgpu_error_type()
}
}

impl Global {
pub fn command_encoder_clear_buffer(
&self,
Expand Down
37 changes: 37 additions & 0 deletions wgpu-core/src/command/compute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::{
PassTimestampWrites, QueryUseError, StateChange,
},
device::{Device, DeviceError, MissingDownlevelFlags, MissingFeatures},
error::{AsWebGpuErrorType, ErrorType},
global::Global,
hal_label, id,
init_tracker::{BufferInitTrackerAction, MemoryInitKind},
Expand Down Expand Up @@ -122,6 +123,12 @@ pub enum DispatchError {
BindingSizeTooSmall(#[from] LateMinBufferBindingSizeMismatch),
}

impl AsWebGpuErrorType for DispatchError {
fn as_webgpu_error_type(&self) -> ErrorType {
ErrorType::Validation
}
}

/// Error encountered when performing a compute pass.
#[derive(Clone, Debug, Error)]
pub enum ComputePassErrorInner {
Expand Down Expand Up @@ -194,6 +201,36 @@ where
}
}

impl AsWebGpuErrorType for ComputePassError {
fn as_webgpu_error_type(&self) -> ErrorType {
let Self { scope: _, inner } = self;
let e: &dyn AsWebGpuErrorType = match inner {
ComputePassErrorInner::Device(e) => e,
ComputePassErrorInner::Encoder(e) => e,
ComputePassErrorInner::DestroyedResource(e) => e,
ComputePassErrorInner::ResourceUsageCompatibility(e) => e,
ComputePassErrorInner::MissingBufferUsage(e) => e,
ComputePassErrorInner::Dispatch(e) => e,
ComputePassErrorInner::Bind(e) => e,
ComputePassErrorInner::PushConstants(e) => e,
ComputePassErrorInner::QueryUse(e) => e,
ComputePassErrorInner::MissingFeatures(e) => e,
ComputePassErrorInner::MissingDownlevelFlags(e) => e,
ComputePassErrorInner::InvalidResource(e) => e,
ComputePassErrorInner::InvalidParentEncoder
| ComputePassErrorInner::BindGroupIndexOutOfRange { .. }
| ComputePassErrorInner::UnalignedIndirectBufferOffset(_)
| ComputePassErrorInner::IndirectBufferOverrun { .. }
| ComputePassErrorInner::InvalidPopDebugGroup
| ComputePassErrorInner::PushConstantOffsetAlignment
| ComputePassErrorInner::PushConstantSizeAlignment
| ComputePassErrorInner::PushConstantOutOfMemory
| ComputePassErrorInner::PassEnded => return ErrorType::Validation,
};
e.as_webgpu_error_type()
}
}

struct State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder> {
binder: Binder,
pipeline: Option<Arc<ComputePipeline>>,
Expand Down
30 changes: 30 additions & 0 deletions wgpu-core/src/command/draw.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{
binding_model::{LateMinBufferBindingSizeMismatch, PushConstantUploadError},
error::{AsWebGpuErrorType, ErrorType},
resource::{
DestroyedResourceError, MissingBufferUsageError, MissingTextureUsageError,
ResourceErrorIdent,
Expand Down Expand Up @@ -62,6 +63,12 @@ pub enum DrawError {
BindingSizeTooSmall(#[from] LateMinBufferBindingSizeMismatch),
}

impl AsWebGpuErrorType for DrawError {
fn as_webgpu_error_type(&self) -> ErrorType {
ErrorType::Validation
}
}

/// Error encountered when encoding a render command.
/// This is the shared error set between render bundles and passes.
#[derive(Clone, Debug, Error)]
Expand Down Expand Up @@ -97,6 +104,29 @@ pub enum RenderCommandError {
Unimplemented(&'static str),
}

impl AsWebGpuErrorType for RenderCommandError {
fn as_webgpu_error_type(&self) -> ErrorType {
let e: &dyn AsWebGpuErrorType = match self {
Self::IncompatiblePipelineTargets(e) => e,
Self::ResourceUsageCompatibility(e) => e,
Self::DestroyedResource(e) => e,
Self::MissingBufferUsage(e) => e,
Self::MissingTextureUsage(e) => e,
Self::PushConstants(e) => e,

Self::BindGroupIndexOutOfRange { .. }
| Self::VertexBufferIndexOutOfRange { .. }
| Self::IncompatibleDepthAccess(..)
| Self::IncompatibleStencilAccess(..)
| Self::InvalidViewportRect(..)
| Self::InvalidViewportDepth(..)
| Self::InvalidScissorRect(..)
| Self::Unimplemented(..) => return ErrorType::Validation,
};
e.as_webgpu_error_type()
}
}

#[derive(Clone, Copy, Debug, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Rect<T> {
Expand Down
21 changes: 21 additions & 0 deletions wgpu-core/src/command/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use self::memory_init::CommandBufferTextureMemoryActions;

use crate::device::queue::TempResource;
use crate::device::{Device, DeviceError, MissingFeatures};
use crate::error::{AsWebGpuErrorType, ErrorType};
use crate::lock::{rank, Mutex};
use crate::snatch::SnatchGuard;

Expand Down Expand Up @@ -745,6 +746,26 @@ pub enum CommandEncoderError {
TimestampWriteIndicesMissing,
}

impl AsWebGpuErrorType for CommandEncoderError {
fn as_webgpu_error_type(&self) -> ErrorType {
let e: &dyn AsWebGpuErrorType = match self {
Self::Device(e) => e,
Self::InvalidColorAttachment(e) => e,
Self::InvalidResource(e) => e,
Self::MissingFeatures(e) => e,
Self::TimestampWritesInvalid(e) => e,
Self::InvalidAttachment(e) => e,

Self::Invalid
| Self::NotRecording
| Self::Locked
| Self::TimestampWriteIndicesEqual { .. }
| Self::TimestampWriteIndicesMissing => return ErrorType::Validation,
};
e.as_webgpu_error_type()
}
}

impl Global {
pub fn command_encoder_finish(
&self,
Expand Down
Loading

0 comments on commit 930d5dc

Please sign in to comment.