Skip to content

Commit b139e29

Browse files
feat: add AsWebGpuErrorType and ErrorType APIs
1 parent 894d036 commit b139e29

18 files changed

Lines changed: 796 additions & 1 deletion

wgpu-core/src/binding_model.rs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use crate::{
1919
device::{
2020
bgl, Device, DeviceError, MissingDownlevelFlags, MissingFeatures, SHADER_STAGE_COUNT,
2121
},
22+
error::{AsWebGpuErrorType, ErrorType},
2223
id::{BindGroupLayoutId, BufferId, SamplerId, TextureViewId, TlasId},
2324
init_tracker::{BufferInitTrackerAction, TextureInitTrackerAction},
2425
pipeline::{ComputePipeline, RenderPipeline},
@@ -78,6 +79,22 @@ pub enum CreateBindGroupLayoutError {
7879
InvalidVisibility(wgt::ShaderStages),
7980
}
8081

82+
impl AsWebGpuErrorType for CreateBindGroupLayoutError {
83+
fn as_webgpu_error_type(&self) -> ErrorType {
84+
match self {
85+
Self::Device(e) => e.as_webgpu_error_type(),
86+
87+
Self::ConflictBinding(_)
88+
| Self::Entry { .. }
89+
| Self::TooManyBindings(_)
90+
| Self::InvalidBindingIndex { .. }
91+
| Self::InvalidVisibility(_)
92+
| Self::ContainsBothBindingArrayAndDynamicOffsetArray
93+
| Self::ContainsBothBindingArrayAndUniformBuffer => ErrorType::Validation,
94+
}
95+
}
96+
}
97+
8198
//TODO: refactor this to move out `enum BindingError`.
8299

83100
#[derive(Clone, Debug, Error)]
@@ -205,6 +222,45 @@ pub enum CreateBindGroupError {
205222
InvalidResource(#[from] InvalidResourceError),
206223
}
207224

225+
impl AsWebGpuErrorType for CreateBindGroupError {
226+
fn as_webgpu_error_type(&self) -> ErrorType {
227+
let e: &dyn AsWebGpuErrorType = match self {
228+
Self::Device(e) => e,
229+
Self::DestroyedResource(e) => e,
230+
Self::MissingBufferUsage(e) => e,
231+
Self::MissingTextureUsage(e) => e,
232+
Self::ResourceUsageCompatibility(e) => e,
233+
Self::InvalidResource(e) => e,
234+
Self::BindingArrayPartialLengthMismatch { .. }
235+
| Self::BindingArrayLengthMismatch { .. }
236+
| Self::BindingArrayZeroLength
237+
| Self::BindingRangeTooLarge { .. }
238+
| Self::BindingSizeTooSmall { .. }
239+
| Self::BindingsNumMismatch { .. }
240+
| Self::BindingZeroSize(_)
241+
| Self::DuplicateBinding(_)
242+
| Self::MissingBindingDeclaration(_)
243+
| Self::SingleBindingExpected
244+
| Self::UnalignedBufferOffset(_, _, _)
245+
| Self::BufferRangeTooLarge { .. }
246+
| Self::WrongBindingType { .. }
247+
| Self::InvalidTextureMultisample { .. }
248+
| Self::InvalidTextureSampleType { .. }
249+
| Self::InvalidTextureDimension { .. }
250+
| Self::InvalidStorageTextureFormat { .. }
251+
| Self::InvalidStorageTextureMipLevelCount { .. }
252+
| Self::WrongSamplerComparison { .. }
253+
| Self::WrongSamplerFiltering { .. }
254+
| Self::DepthStencilAspect
255+
| Self::StorageReadNotSupported(_)
256+
| Self::StorageWriteNotSupported(_)
257+
| Self::StorageReadWriteNotSupported(_)
258+
| Self::StorageAtomicNotSupported(_) => return ErrorType::Validation,
259+
};
260+
e.as_webgpu_error_type()
261+
}
262+
}
263+
208264
#[derive(Clone, Debug, Error)]
209265
pub enum BindingZone {
210266
#[error("Stage {0:?}")]
@@ -222,6 +278,12 @@ pub struct BindingTypeMaxCountError {
222278
pub count: u32,
223279
}
224280

281+
impl AsWebGpuErrorType for BindingTypeMaxCountError {
282+
fn as_webgpu_error_type(&self) -> ErrorType {
283+
ErrorType::Validation
284+
}
285+
}
286+
225287
#[derive(Clone, Debug)]
226288
pub enum BindingTypeMaxCountErrorKind {
227289
DynamicUniformBuffers,
@@ -665,6 +727,22 @@ pub enum CreatePipelineLayoutError {
665727
InvalidResource(#[from] InvalidResourceError),
666728
}
667729

730+
impl AsWebGpuErrorType for CreatePipelineLayoutError {
731+
fn as_webgpu_error_type(&self) -> ErrorType {
732+
let e: &dyn AsWebGpuErrorType = match self {
733+
Self::Device(e) => e,
734+
Self::MissingFeatures(e) => e,
735+
Self::InvalidResource(e) => e,
736+
Self::TooManyBindings(e) => e,
737+
Self::MisalignedPushConstantRange { .. }
738+
| Self::MoreThanOnePushConstantRangePerStage { .. }
739+
| Self::PushConstantRangeTooLarge { .. }
740+
| Self::TooManyGroups { .. } => return ErrorType::Validation,
741+
};
742+
e.as_webgpu_error_type()
743+
}
744+
}
745+
668746
#[derive(Clone, Debug, Error)]
669747
#[non_exhaustive]
670748
pub enum PushConstantUploadError {
@@ -696,6 +774,12 @@ pub enum PushConstantUploadError {
696774
Unaligned(u32),
697775
}
698776

777+
impl AsWebGpuErrorType for PushConstantUploadError {
778+
fn as_webgpu_error_type(&self) -> ErrorType {
779+
ErrorType::Validation
780+
}
781+
}
782+
699783
/// Describes a pipeline layout.
700784
///
701785
/// A `PipelineLayoutDescriptor` can be used to create a pipeline layout.
@@ -938,6 +1022,12 @@ pub enum BindError {
9381022
},
9391023
}
9401024

1025+
impl AsWebGpuErrorType for BindError {
1026+
fn as_webgpu_error_type(&self) -> ErrorType {
1027+
ErrorType::Validation
1028+
}
1029+
}
1030+
9411031
#[derive(Debug)]
9421032
pub struct BindGroupDynamicBindingData {
9431033
/// The index of the binding.
@@ -1099,6 +1189,15 @@ pub enum GetBindGroupLayoutError {
10991189
InvalidResource(#[from] InvalidResourceError),
11001190
}
11011191

1192+
impl AsWebGpuErrorType for GetBindGroupLayoutError {
1193+
fn as_webgpu_error_type(&self) -> ErrorType {
1194+
match self {
1195+
Self::InvalidGroupIndex(_) => ErrorType::Validation,
1196+
Self::InvalidResource(e) => e.as_webgpu_error_type(),
1197+
}
1198+
}
1199+
}
1200+
11021201
#[derive(Clone, Debug, Error, Eq, PartialEq)]
11031202
#[error("Buffer is bound with size {bound_size} where the shader expects {shader_size} in group[{group_index}] compact index {compact_index}")]
11041203
pub struct LateMinBufferBindingSizeMismatch {

wgpu-core/src/command/bundle.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ use crate::{
102102
AttachmentData, Device, DeviceError, MissingDownlevelFlags, RenderPassContext,
103103
SHADER_STAGE_COUNT,
104104
},
105+
error::{AsWebGpuErrorType, ErrorType},
105106
hub::Hub,
106107
id,
107108
init_tracker::{BufferInitTrackerAction, MemoryInitKind, TextureInitTrackerAction},
@@ -829,6 +830,15 @@ pub enum CreateRenderBundleError {
829830
InvalidSampleCount(u32),
830831
}
831832

833+
impl AsWebGpuErrorType for CreateRenderBundleError {
834+
fn as_webgpu_error_type(&self) -> ErrorType {
835+
match self {
836+
Self::ColorAttachment(e) => e.as_webgpu_error_type(),
837+
Self::InvalidSampleCount(_) => ErrorType::Validation,
838+
}
839+
}
840+
}
841+
832842
/// Error type returned from `RenderBundleEncoder::new` if the sample count is invalid.
833843
#[derive(Clone, Debug, Error)]
834844
#[non_exhaustive]
@@ -1479,6 +1489,21 @@ pub struct RenderBundleError {
14791489
inner: RenderBundleErrorInner,
14801490
}
14811491

1492+
impl AsWebGpuErrorType for RenderBundleError {
1493+
fn as_webgpu_error_type(&self) -> ErrorType {
1494+
let Self { scope: _, inner } = self;
1495+
let e: &dyn AsWebGpuErrorType = match inner {
1496+
RenderBundleErrorInner::Device(e) => e,
1497+
RenderBundleErrorInner::RenderCommand(e) => e,
1498+
RenderBundleErrorInner::Draw(e) => e,
1499+
RenderBundleErrorInner::MissingDownlevelFlags(e) => e,
1500+
RenderBundleErrorInner::Bind(e) => e,
1501+
RenderBundleErrorInner::InvalidResource(e) => e,
1502+
};
1503+
e.as_webgpu_error_type()
1504+
}
1505+
}
1506+
14821507
impl RenderBundleError {
14831508
pub fn from_device_error(e: DeviceError) -> Self {
14841509
Self {

wgpu-core/src/command/clear.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::{
77
api_log,
88
command::CommandEncoderError,
99
device::DeviceError,
10+
error::{AsWebGpuErrorType, ErrorType},
1011
get_lowest_common_denom,
1112
global::Global,
1213
id::{BufferId, CommandEncoderId, TextureId},
@@ -79,6 +80,28 @@ whereas subesource range specified start {subresource_base_array_layer} and coun
7980
InvalidResource(#[from] InvalidResourceError),
8081
}
8182

83+
impl AsWebGpuErrorType for ClearError {
84+
fn as_webgpu_error_type(&self) -> ErrorType {
85+
let e: &dyn AsWebGpuErrorType = match self {
86+
Self::DestroyedResource(e) => e,
87+
Self::MissingBufferUsage(e) => e,
88+
Self::Device(e) => e,
89+
Self::CommandEncoderError(e) => e,
90+
Self::InvalidResource(e) => e,
91+
Self::NoValidTextureClearMode(..)
92+
| Self::MissingClearTextureFeature
93+
| Self::UnalignedFillSize(..)
94+
| Self::UnalignedBufferOffset(..)
95+
| Self::OffsetPlusSizeExceeds64BitBounds { .. }
96+
| Self::BufferOverrun { .. }
97+
| Self::MissingTextureAspect { .. }
98+
| Self::InvalidTextureLevelRange { .. }
99+
| Self::InvalidTextureLayerRange { .. } => return ErrorType::Validation,
100+
};
101+
e.as_webgpu_error_type()
102+
}
103+
}
104+
82105
impl Global {
83106
pub fn command_encoder_clear_buffer(
84107
&self,

wgpu-core/src/command/compute.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use crate::{
2020
PassTimestampWrites, QueryUseError, StateChange,
2121
},
2222
device::{Device, DeviceError, MissingDownlevelFlags, MissingFeatures},
23+
error::{AsWebGpuErrorType, ErrorType},
2324
global::Global,
2425
hal_label, id,
2526
init_tracker::{BufferInitTrackerAction, MemoryInitKind},
@@ -121,6 +122,12 @@ pub enum DispatchError {
121122
BindingSizeTooSmall(#[from] LateMinBufferBindingSizeMismatch),
122123
}
123124

125+
impl AsWebGpuErrorType for DispatchError {
126+
fn as_webgpu_error_type(&self) -> ErrorType {
127+
ErrorType::Validation
128+
}
129+
}
130+
124131
/// Error encountered when performing a compute pass.
125132
#[derive(Clone, Debug, Error)]
126133
pub enum ComputePassErrorInner {
@@ -193,6 +200,36 @@ where
193200
}
194201
}
195202

203+
impl AsWebGpuErrorType for ComputePassError {
204+
fn as_webgpu_error_type(&self) -> ErrorType {
205+
let Self { scope: _, inner } = self;
206+
let e: &dyn AsWebGpuErrorType = match inner {
207+
ComputePassErrorInner::Device(e) => e,
208+
ComputePassErrorInner::Encoder(e) => e,
209+
ComputePassErrorInner::DestroyedResource(e) => e,
210+
ComputePassErrorInner::ResourceUsageCompatibility(e) => e,
211+
ComputePassErrorInner::MissingBufferUsage(e) => e,
212+
ComputePassErrorInner::Dispatch(e) => e,
213+
ComputePassErrorInner::Bind(e) => e,
214+
ComputePassErrorInner::PushConstants(e) => e,
215+
ComputePassErrorInner::QueryUse(e) => e,
216+
ComputePassErrorInner::MissingFeatures(e) => e,
217+
ComputePassErrorInner::MissingDownlevelFlags(e) => e,
218+
ComputePassErrorInner::InvalidResource(e) => e,
219+
ComputePassErrorInner::InvalidParentEncoder
220+
| ComputePassErrorInner::BindGroupIndexOutOfRange { .. }
221+
| ComputePassErrorInner::UnalignedIndirectBufferOffset(_)
222+
| ComputePassErrorInner::IndirectBufferOverrun { .. }
223+
| ComputePassErrorInner::InvalidPopDebugGroup
224+
| ComputePassErrorInner::PushConstantOffsetAlignment
225+
| ComputePassErrorInner::PushConstantSizeAlignment
226+
| ComputePassErrorInner::PushConstantOutOfMemory
227+
| ComputePassErrorInner::PassEnded => return ErrorType::Validation,
228+
};
229+
e.as_webgpu_error_type()
230+
}
231+
}
232+
196233
struct State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder> {
197234
binder: Binder,
198235
pipeline: Option<Arc<ComputePipeline>>,

wgpu-core/src/command/draw.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use thiserror::Error;
44

55
use crate::{
66
binding_model::{LateMinBufferBindingSizeMismatch, PushConstantUploadError},
7+
error::{AsWebGpuErrorType, ErrorType},
78
resource::{
89
DestroyedResourceError, MissingBufferUsageError, MissingTextureUsageError,
910
ResourceErrorIdent,
@@ -56,6 +57,12 @@ pub enum DrawError {
5657
BindingSizeTooSmall(#[from] LateMinBufferBindingSizeMismatch),
5758
}
5859

60+
impl AsWebGpuErrorType for DrawError {
61+
fn as_webgpu_error_type(&self) -> ErrorType {
62+
ErrorType::Validation
63+
}
64+
}
65+
5966
/// Error encountered when encoding a render command.
6067
/// This is the shared error set between render bundles and passes.
6168
#[derive(Clone, Debug, Error)]
@@ -91,6 +98,29 @@ pub enum RenderCommandError {
9198
Unimplemented(&'static str),
9299
}
93100

101+
impl AsWebGpuErrorType for RenderCommandError {
102+
fn as_webgpu_error_type(&self) -> ErrorType {
103+
let e: &dyn AsWebGpuErrorType = match self {
104+
Self::IncompatiblePipelineTargets(e) => e,
105+
Self::ResourceUsageCompatibility(e) => e,
106+
Self::DestroyedResource(e) => e,
107+
Self::MissingBufferUsage(e) => e,
108+
Self::MissingTextureUsage(e) => e,
109+
Self::PushConstants(e) => e,
110+
111+
Self::BindGroupIndexOutOfRange { .. }
112+
| Self::VertexBufferIndexOutOfRange { .. }
113+
| Self::IncompatibleDepthAccess(..)
114+
| Self::IncompatibleStencilAccess(..)
115+
| Self::InvalidViewportRect(..)
116+
| Self::InvalidViewportDepth(..)
117+
| Self::InvalidScissorRect(..)
118+
| Self::Unimplemented(..) => return ErrorType::Validation,
119+
};
120+
e.as_webgpu_error_type()
121+
}
122+
}
123+
94124
#[derive(Clone, Copy, Debug, Default)]
95125
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
96126
pub struct Rect<T> {

wgpu-core/src/command/mod.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use self::memory_init::CommandBufferTextureMemoryActions;
3232

3333
use crate::device::queue::TempResource;
3434
use crate::device::{Device, DeviceError, MissingFeatures};
35+
use crate::error::{AsWebGpuErrorType, ErrorType};
3536
use crate::lock::{rank, Mutex};
3637
use crate::snatch::SnatchGuard;
3738

@@ -747,6 +748,26 @@ pub enum CommandEncoderError {
747748
TimestampWriteIndicesMissing,
748749
}
749750

751+
impl AsWebGpuErrorType for CommandEncoderError {
752+
fn as_webgpu_error_type(&self) -> ErrorType {
753+
let e: &dyn AsWebGpuErrorType = match self {
754+
Self::Device(e) => e,
755+
Self::InvalidColorAttachment(e) => e,
756+
Self::InvalidResource(e) => e,
757+
Self::MissingFeatures(e) => e,
758+
Self::TimestampWritesInvalid(e) => e,
759+
Self::InvalidAttachment(e) => e,
760+
761+
Self::Invalid
762+
| Self::NotRecording
763+
| Self::Locked
764+
| Self::TimestampWriteIndicesEqual { .. }
765+
| Self::TimestampWriteIndicesMissing => return ErrorType::Validation,
766+
};
767+
e.as_webgpu_error_type()
768+
}
769+
}
770+
750771
impl Global {
751772
pub fn command_encoder_finish(
752773
&self,

0 commit comments

Comments
 (0)