diff --git a/wgpu-core/src/binding_model.rs b/wgpu-core/src/binding_model.rs index b20e31482..3c1b507e1 100644 --- a/wgpu-core/src/binding_model.rs +++ b/wgpu-core/src/binding_model.rs @@ -1,5 +1,6 @@ use crate::{ device::{DeviceError, MissingDownlevelFlags, MissingFeatures, SHADER_STAGE_COUNT}, + error::{ErrorFormatter, PrettyError}, hub::Resource, id::{BindGroupLayoutId, BufferId, DeviceId, SamplerId, TextureViewId, Valid}, memory_init_tracker::MemoryInitTrackerAction, @@ -155,6 +156,33 @@ pub enum CreateBindGroupError { ResourceUsageConflict(#[from] UsageConflict), } +impl PrettyError for CreateBindGroupError { + fn fmt_pretty(&self, fmt: &mut ErrorFormatter) { + fmt.error(self); + match *self { + Self::BindingZeroSize(id) => { + fmt.buffer_label(&id); + } + Self::BindingRangeTooLarge { buffer, .. } => { + fmt.buffer_label(&buffer); + } + Self::BindingSizeTooSmall { buffer, .. } => { + fmt.buffer_label(&buffer); + } + Self::InvalidBuffer(id) => { + fmt.buffer_label(&id); + } + Self::InvalidTextureView(id) => { + fmt.texture_view_label(&id); + } + Self::InvalidSampler(id) => { + fmt.sampler_label(&id); + } + _ => {} + }; + } +} + #[derive(Clone, Debug, Error)] pub enum BindingZone { #[error("stage {0:?}")] @@ -441,6 +469,15 @@ pub enum CreatePipelineLayoutError { TooManyGroups { actual: usize, max: usize }, } +impl PrettyError for CreatePipelineLayoutError { + fn fmt_pretty(&self, fmt: &mut ErrorFormatter) { + fmt.error(self); + if let Self::InvalidBindGroupLayout(id) = *self { + fmt.bind_group_layout_label(&id); + }; + } +} + #[derive(Clone, Debug, Error)] pub enum PushConstantUploadError { #[error("provided push constant with indices {offset}..{end_offset} overruns matching push constant range at index {idx}, with stage(s) {:?} and indices {:?}", range.stages, range.range)] diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs index 3ba7a1e56..d51e543d1 100644 --- a/wgpu-core/src/command/bundle.rs +++ b/wgpu-core/src/command/bundle.rs @@ -43,6 +43,7 @@ use crate::{ AttachmentData, Device, DeviceError, MissingDownlevelFlags, RenderPassContext, SHADER_STAGE_COUNT, }, + error::{ErrorFormatter, PrettyError}, hub::{GlobalIdentityHandlerFactory, HalApi, Hub, Resource, Storage, Token}, id, memory_init_tracker::{MemoryInitKind, MemoryInitTrackerAction}, @@ -560,6 +561,17 @@ pub enum ExecutionError { #[error("using {0} in a render bundle is not implemented")] Unimplemented(&'static str), } +impl PrettyError for ExecutionError { + fn fmt_pretty(&self, fmt: &mut ErrorFormatter) { + fmt.error(self); + match *self { + Self::DestroyedBuffer(id) => { + fmt.buffer_label(&id); + } + Self::Unimplemented(_reason) => {} + }; + } +} pub type RenderBundleDescriptor<'a> = wgt::RenderBundleDescriptor>; @@ -1161,6 +1173,14 @@ impl RenderBundleError { inner: RenderBundleErrorInner::Device(DeviceError::Invalid), }; } +impl PrettyError for RenderBundleError { + fn fmt_pretty(&self, fmt: &mut ErrorFormatter) { + // This error is wrapper for the inner error, + // but the scope has useful labels + fmt.error(self); + self.scope.fmt_pretty(fmt); + } +} impl MapPassErr for Result where diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index c8c444aa6..23f080cc1 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -6,6 +6,7 @@ use crate::{ StateChange, }, device::MissingDownlevelFlags, + error::{ErrorFormatter, PrettyError}, hub::{Global, GlobalIdentityHandlerFactory, HalApi, Storage, Token}, id, memory_init_tracker::{MemoryInitKind, MemoryInitTrackerAction}, @@ -161,6 +162,24 @@ pub enum ComputePassErrorInner { MissingDownlevelFlags(#[from] MissingDownlevelFlags), } +impl PrettyError for ComputePassErrorInner { + fn fmt_pretty(&self, fmt: &mut ErrorFormatter) { + fmt.error(self); + match *self { + Self::InvalidBindGroup(id) => { + fmt.bind_group_label(&id); + } + Self::InvalidPipeline(id) => { + fmt.compute_pipeline_label(&id); + } + Self::InvalidIndirectBuffer(id) => { + fmt.buffer_label(&id); + } + _ => {} + }; + } +} + /// Error encountered when performing a compute pass. #[derive(Clone, Debug, Error)] #[error("{scope}")] @@ -169,6 +188,14 @@ pub struct ComputePassError { #[source] inner: ComputePassErrorInner, } +impl PrettyError for ComputePassError { + fn fmt_pretty(&self, fmt: &mut ErrorFormatter) { + // This error is wrapper for the inner error, + // but the scope has useful labels + fmt.error(self); + self.scope.fmt_pretty(fmt); + } +} impl MapPassErr for Result where diff --git a/wgpu-core/src/command/draw.rs b/wgpu-core/src/command/draw.rs index e9b266392..0a1e422e8 100644 --- a/wgpu-core/src/command/draw.rs +++ b/wgpu-core/src/command/draw.rs @@ -3,6 +3,7 @@ use crate::{ binding_model::PushConstantUploadError, + error::ErrorFormatter, id, track::UseExtendError, validation::{MissingBufferUsageError, MissingTextureUsageError}, @@ -93,6 +94,23 @@ pub enum RenderCommandError { #[error("Support for {0} is not implemented yet")] Unimplemented(&'static str), } +impl crate::error::PrettyError for RenderCommandError { + fn fmt_pretty(&self, fmt: &mut ErrorFormatter) { + fmt.error(self); + match *self { + Self::InvalidBindGroup(id) => { + fmt.bind_group_label(&id); + } + Self::InvalidPipeline(id) => { + fmt.render_pipeline_label(&id); + } + Self::Buffer(id, ..) | Self::DestroyedBuffer(id) => { + fmt.buffer_label(&id); + } + _ => {} + }; + } +} #[derive(Clone, Copy, Debug, Default)] #[cfg_attr( diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index 16ffc7b70..610a547a5 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -14,6 +14,7 @@ pub use self::query::*; pub use self::render::*; pub use self::transfer::*; +use crate::error::{ErrorFormatter, PrettyError}; use crate::{ hub::{Global, GlobalIdentityHandlerFactory, HalApi, Storage, Token}, id, @@ -499,3 +500,40 @@ pub enum PassErrorScope { #[error("In a pop_debug_group command")] PopDebugGroup, } + +impl PrettyError for PassErrorScope { + fn fmt_pretty(&self, fmt: &mut ErrorFormatter) { + // This error is not in the error chain, only notes are needed + match *self { + Self::Pass(id) => { + fmt.command_buffer_label(&id); + } + Self::SetBindGroup(id) => { + fmt.bind_group_label(&id); + } + Self::SetPipelineRender(id) => { + fmt.render_pipeline_label(&id); + } + Self::SetPipelineCompute(id) => { + fmt.compute_pipeline_label(&id); + } + Self::SetVertexBuffer(id) => { + fmt.buffer_label(&id); + } + Self::SetIndexBuffer(id) => { + fmt.buffer_label(&id); + } + Self::Draw { + pipeline: Some(id), .. + } => { + fmt.render_pipeline_label(&id); + } + Self::Dispatch { + pipeline: Some(id), .. + } => { + fmt.compute_pipeline_label(&id); + } + _ => {} + } + } +} diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 3bfcb7a8f..9d5c9e1ee 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -10,6 +10,7 @@ use crate::{ AttachmentData, MissingDownlevelFlags, MissingFeatures, RenderPassCompatibilityError, RenderPassContext, }, + error::{ErrorFormatter, PrettyError}, hub::{Global, GlobalIdentityHandlerFactory, HalApi, Storage, Token}, id, memory_init_tracker::{MemoryInitKind, MemoryInitTrackerAction}, @@ -458,6 +459,15 @@ pub enum RenderPassErrorInner { QueryUse(#[from] QueryUseError), } +impl PrettyError for RenderPassErrorInner { + fn fmt_pretty(&self, fmt: &mut ErrorFormatter) { + fmt.error(self); + if let Self::InvalidAttachment(id) = *self { + fmt.texture_view_label_with_key(&id, "attachment"); + }; + } +} + impl From for RenderPassErrorInner { fn from(error: MissingBufferUsageError) -> Self { Self::RenderCommand(error.into()) @@ -478,6 +488,14 @@ pub struct RenderPassError { #[source] inner: RenderPassErrorInner, } +impl PrettyError for RenderPassError { + fn fmt_pretty(&self, fmt: &mut ErrorFormatter) { + // This error is wrapper for the inner error, + // but the scope has useful labels + fmt.error(self); + self.scope.fmt_pretty(fmt); + } +} impl MapPassErr for Result where diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 03928b4e5..ee945216d 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -3,6 +3,7 @@ use crate::device::trace::Command as TraceCommand; use crate::{ command::{CommandBuffer, CommandEncoderError}, conv, + error::{ErrorFormatter, PrettyError}, hub::{Global, GlobalIdentityHandlerFactory, HalApi, Storage, Token}, id::{BufferId, CommandEncoderId, TextureId}, memory_init_tracker::{MemoryInitKind, MemoryInitTrackerAction}, @@ -92,6 +93,38 @@ pub enum TransferError { CopyToForbiddenTextureFormat(wgt::TextureFormat), } +impl PrettyError for TransferError { + fn fmt_pretty(&self, fmt: &mut ErrorFormatter) { + fmt.error(self); + match *self { + Self::InvalidBuffer(id) => { + fmt.buffer_label(&id); + } + Self::InvalidTexture(id) => { + fmt.texture_label(&id); + } + // Self::MissingCopySrcUsageFlag(buf_opt, tex_opt) => { + // if let Some(buf) = buf_opt { + // let name = crate::gfx_select!(buf => global.buffer_label(buf)); + // ret.push_str(&format_label_line("source", &name)); + // } + // if let Some(tex) = tex_opt { + // let name = crate::gfx_select!(tex => global.texture_label(tex)); + // ret.push_str(&format_label_line("source", &name)); + // } + // } + Self::MissingCopyDstUsageFlag(buf_opt, tex_opt) => { + if let Some(buf) = buf_opt { + fmt.buffer_label_with_key(&buf, "destination"); + } + if let Some(tex) = tex_opt { + fmt.texture_label_with_key(&tex, "destination"); + } + } + _ => {} + }; + } +} /// Error encountered while attempting to do a copy on a command encoder. #[derive(Clone, Debug, Error)] pub enum CopyError { diff --git a/wgpu-core/src/error.rs b/wgpu-core/src/error.rs new file mode 100644 index 000000000..fa023a94a --- /dev/null +++ b/wgpu-core/src/error.rs @@ -0,0 +1,175 @@ +use core::fmt; +use std::error::Error; + +use crate::{ + gfx_select, + hub::{Global, IdentityManagerFactory}, +}; + +pub struct ErrorFormatter<'a> { + writer: &'a mut dyn fmt::Write, + global: &'a Global, +} + +impl<'a> ErrorFormatter<'a> { + pub fn error(&mut self, err: &dyn Error) { + writeln!(self.writer, " {}", err).expect("Error formatting error"); + } + + pub fn note(&mut self, note: &dyn fmt::Display) { + writeln!(self.writer, " note: {}", note).expect("Error formatting error"); + } + + pub fn label(&mut self, label_key: &str, label_value: &str) { + if !label_key.is_empty() && !label_value.is_empty() { + self.note(&format!("{} = `{}`", label_key, label_value)); + } + } + + pub fn bind_group_label(&mut self, id: &crate::id::BindGroupId) { + let global = self.global; + let label = gfx_select!(id => global.bind_group_label(*id)); + self.label("bind group", &label); + } + + pub fn bind_group_layout_label(&mut self, id: &crate::id::BindGroupLayoutId) { + let global = self.global; + let label = gfx_select!(id => global.bind_group_layout_label(*id)); + self.label("bind group layout", &label); + } + + pub fn render_pipeline_label(&mut self, id: &crate::id::RenderPipelineId) { + let global = self.global; + let label = gfx_select!(id => global.render_pipeline_label(*id)); + self.label("render pipeline", &label); + } + + pub fn compute_pipeline_label(&mut self, id: &crate::id::ComputePipelineId) { + let global = self.global; + let label = gfx_select!(id => global.compute_pipeline_label(*id)); + self.label("compute pipeline", &label); + } + + pub fn buffer_label_with_key(&mut self, id: &crate::id::BufferId, key: &str) { + let global = self.global; + let label = gfx_select!(id => global.buffer_label(*id)); + self.label(key, &label); + } + + pub fn buffer_label(&mut self, id: &crate::id::BufferId) { + self.buffer_label_with_key(id, "buffer"); + } + + pub fn texture_label_with_key(&mut self, id: &crate::id::TextureId, key: &str) { + let global = self.global; + let label = gfx_select!(id => global.texture_label(*id)); + self.label(key, &label); + } + + pub fn texture_label(&mut self, id: &crate::id::TextureId) { + self.texture_label_with_key(id, "texture"); + } + + pub fn texture_view_label_with_key(&mut self, id: &crate::id::TextureViewId, key: &str) { + let global = self.global; + let label = gfx_select!(id => global.texture_view_label(*id)); + self.label(key, &label); + } + + pub fn texture_view_label(&mut self, id: &crate::id::TextureViewId) { + self.texture_view_label_with_key(id, "texture view"); + } + + pub fn sampler_label(&mut self, id: &crate::id::SamplerId) { + let global = self.global; + let label = gfx_select!(id => global.sampler_label(*id)); + self.label("sampler", &label); + } + + pub fn command_buffer_label(&mut self, id: &crate::id::CommandBufferId) { + let global = self.global; + let label = gfx_select!(id => global.command_buffer_label(*id)); + self.label("command buffer", &label); + } +} + +pub trait PrettyError: Error + Sized { + fn fmt_pretty(&self, fmt: &mut ErrorFormatter) { + fmt.error(self); + } +} + +pub fn format_pretty_any( + writer: &mut dyn fmt::Write, + global: &Global, + error: &(dyn Error + 'static), +) { + let mut fmt = ErrorFormatter { writer, global }; + + if let Some(pretty_err) = error.downcast_ref::() { + return pretty_err.fmt_pretty(&mut fmt); + } + + if let Some(pretty_err) = error.downcast_ref::() { + return pretty_err.fmt_pretty(&mut fmt); + } + if let Some(pretty_err) = error.downcast_ref::() { + return pretty_err.fmt_pretty(&mut fmt); + } + if let Some(pretty_err) = + error.downcast_ref::() + { + return pretty_err.fmt_pretty(&mut fmt); + } + if let Some(pretty_err) = error.downcast_ref::() { + return pretty_err.fmt_pretty(&mut fmt); + } + if let Some(pretty_err) = error.downcast_ref::() { + return pretty_err.fmt_pretty(&mut fmt); + } + if let Some(pretty_err) = error.downcast_ref::() { + return pretty_err.fmt_pretty(&mut fmt); + } + if let Some(pretty_err) = error.downcast_ref::() { + return pretty_err.fmt_pretty(&mut fmt); + } + if let Some(pretty_err) = error.downcast_ref::() { + return pretty_err.fmt_pretty(&mut fmt); + } + if let Some(pretty_err) = error.downcast_ref::() { + return pretty_err.fmt_pretty(&mut fmt); + } + if let Some(pretty_err) = error.downcast_ref::() { + return pretty_err.fmt_pretty(&mut fmt); + } + + // default + fmt.error(error) +} + +#[derive(Debug)] +pub struct ContextError { + pub string: &'static str, + pub cause: Box, + pub label_key: &'static str, + pub label: String, +} + +impl PrettyError for ContextError { + fn fmt_pretty(&self, fmt: &mut ErrorFormatter) { + fmt.error(self); + fmt.label(self.label_key, &self.label); + } +} + +impl fmt::Display for ContextError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "In {}", self.string) + } +} + +impl Error for ContextError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + Some(self.cause.as_ref()) + } +} diff --git a/wgpu-core/src/lib.rs b/wgpu-core/src/lib.rs index 968eff3e6..37bc00f8e 100644 --- a/wgpu-core/src/lib.rs +++ b/wgpu-core/src/lib.rs @@ -34,6 +34,7 @@ pub mod binding_model; pub mod command; mod conv; pub mod device; +pub mod error; pub mod hub; pub mod id; pub mod instance; diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 959e57539..b3e4530f3 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -1,9 +1,8 @@ use crate::{ - backend::{error::ContextError, native_gpu_future}, - AdapterInfo, BindGroupDescriptor, BindGroupLayoutDescriptor, BindingResource, BufferBinding, - CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor, - DownlevelCapabilities, Features, Label, Limits, LoadOp, MapMode, Operations, - PipelineLayoutDescriptor, RenderBundleEncoderDescriptor, RenderPipelineDescriptor, + backend::native_gpu_future, AdapterInfo, BindGroupDescriptor, BindGroupLayoutDescriptor, + BindingResource, BufferBinding, CommandEncoderDescriptor, ComputePassDescriptor, + ComputePipelineDescriptor, DownlevelCapabilities, Features, Label, Limits, LoadOp, MapMode, + Operations, PipelineLayoutDescriptor, RenderBundleEncoderDescriptor, RenderPipelineDescriptor, SamplerDescriptor, ShaderModuleDescriptor, ShaderModuleDescriptorSpirV, ShaderSource, SwapChainStatus, TextureDescriptor, TextureFormat, TextureViewDescriptor, }; @@ -144,7 +143,7 @@ impl Context { label: Label, string: &'static str, ) { - let error = ContextError { + let error = wgc::error::ContextError { string, cause: Box::new(cause), label: label.unwrap_or_default().to_string(), @@ -186,6 +185,25 @@ impl Context { ) -> ! { panic!("Error in {}: {}", string, cause); } + + fn format_error(&self, err: &(impl Error + 'static)) -> String { + let global = self.global(); + let mut err_descs = vec![]; + + let mut err_str = String::new(); + wgc::error::format_pretty_any(&mut err_str, global, err); + err_descs.push(err_str); + + let mut source_opt = err.source(); + while let Some(source) = source_opt { + let mut source_str = String::new(); + wgc::error::format_pretty_any(&mut source_str, global, source); + err_descs.push(source_str); + source_opt = source.source(); + } + + format!("Validation Error\n\nCaused by:\n{}", err_descs.join("")) + } } mod pass_impl { diff --git a/wgpu/src/backend/error.rs b/wgpu/src/backend/error.rs deleted file mode 100644 index 556e42fbf..000000000 --- a/wgpu/src/backend/error.rs +++ /dev/null @@ -1,333 +0,0 @@ -use std::{error::Error, fmt}; - -#[derive(Debug)] -pub(super) struct ContextError { - pub string: &'static str, - pub cause: Box, - pub label_key: &'static str, - pub label: String, -} - -impl fmt::Display for ContextError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "In {}", self.string) - } -} - -impl Error for ContextError { - fn source(&self) -> Option<&(dyn Error + 'static)> { - Some(self.cause.as_ref()) - } -} - -impl super::Context { - pub(super) fn format_error(&self, err: &(impl Error + 'static)) -> String { - let mut err_descs = vec![self.format_pretty_any(err)]; - - let mut source_opt = err.source(); - while let Some(source) = source_opt { - err_descs.push(self.format_pretty_any(source)); - source_opt = source.source(); - } - - format!("Validation Error\n\nCaused by:\n{}", err_descs.join("")) - } - - fn format_pretty_any(&self, error: &(dyn Error + 'static)) -> String { - if let Some(pretty_err) = error.downcast_ref::() { - return pretty_err.fmt_pretty(self); - } - if let Some(pretty_err) = error.downcast_ref::() { - return pretty_err.fmt_pretty(self); - } - if let Some(pretty_err) = error.downcast_ref::() { - return pretty_err.fmt_pretty(self); - } - if let Some(pretty_err) = - error.downcast_ref::() - { - return pretty_err.fmt_pretty(self); - } - if let Some(pretty_err) = error.downcast_ref::() { - return pretty_err.fmt_pretty(self); - } - if let Some(pretty_err) = error.downcast_ref::() { - return pretty_err.fmt_pretty(self); - } - if let Some(pretty_err) = error.downcast_ref::() { - return pretty_err.fmt_pretty(self); - } - if let Some(pretty_err) = error.downcast_ref::() { - return pretty_err.fmt_pretty(self); - } - if let Some(pretty_err) = error.downcast_ref::() { - return pretty_err.fmt_pretty(self); - } - if let Some(pretty_err) = error.downcast_ref::() { - return pretty_err.fmt_pretty(self); - } - if let Some(pretty_err) = error.downcast_ref::() { - return pretty_err.fmt_pretty(self); - } - - // default - format_error_line(error.as_display()) - } -} - -pub(super) fn format_error_line(err: &dyn fmt::Display) -> String { - format!(" {}\n", err) -} - -pub(super) fn format_note_line(note: &dyn fmt::Display) -> String { - format!(" note: {}\n", note) -} - -pub(super) fn format_label_line(label_key: &str, label_value: &str) -> String { - if label_key.is_empty() || label_value.is_empty() { - String::new() - } else { - format_note_line(&format!("{} = `{}`", label_key, label_value)) - } -} - -trait AsDisplay { - fn as_display(&self) -> &dyn fmt::Display; -} - -impl AsDisplay for T { - fn as_display(&self) -> &dyn fmt::Display { - self - } -} - -pub trait PrettyError: Error { - fn fmt_pretty(&self, _context: &super::Context) -> String { - format_error_line(self.as_display()) - } -} - -impl PrettyError for ContextError { - fn fmt_pretty(&self, _context: &super::Context) -> String { - format_error_line(self.as_display()) + &format_label_line(self.label_key, &self.label) - } -} - -impl PrettyError for wgc::command::RenderCommandError { - fn fmt_pretty(&self, context: &super::Context) -> String { - let global = context.global(); - let mut ret = format_error_line(self); - match *self { - Self::InvalidBindGroup(id) => { - let name = wgc::gfx_select!(id => global.bind_group_label(id)); - ret.push_str(&format_label_line("bind group", &name)); - } - Self::InvalidPipeline(id) => { - let name = wgc::gfx_select!(id => global.render_pipeline_label(id)); - ret.push_str(&format_label_line("render pipeline", &name)); - } - Self::Buffer(id, ..) | Self::DestroyedBuffer(id) => { - let name = wgc::gfx_select!(id => global.buffer_label(id)); - ret.push_str(&format_label_line("buffer", &name)); - } - _ => {} - }; - ret - } -} -impl PrettyError for wgc::binding_model::CreateBindGroupError { - fn fmt_pretty(&self, context: &super::Context) -> String { - let global = context.global(); - let mut ret = format_error_line(self); - match *self { - Self::InvalidBuffer(id) => { - let name = wgc::gfx_select!(id => global.buffer_label(id)); - ret.push_str(&format_label_line("buffer", &name)); - } - Self::InvalidTextureView(id) => { - let name = wgc::gfx_select!(id => global.texture_view_label(id)); - ret.push_str(&format_label_line("texture view", &name)); - } - Self::InvalidSampler(id) => { - let name = wgc::gfx_select!(id => global.sampler_label(id)); - ret.push_str(&format_label_line("sampler", &name)); - } - _ => {} - }; - ret - } -} - -impl PrettyError for wgc::binding_model::CreatePipelineLayoutError { - fn fmt_pretty(&self, context: &super::Context) -> String { - let global = context.global(); - let mut ret = format_error_line(self); - if let Self::InvalidBindGroupLayout(id) = *self { - let name = wgc::gfx_select!(id => global.bind_group_layout_label(id)); - ret.push_str(&format_label_line("bind group layout", &name)); - }; - ret - } -} - -impl PrettyError for wgc::command::ExecutionError { - fn fmt_pretty(&self, context: &super::Context) -> String { - let global = context.global(); - let mut ret = format_error_line(self); - match *self { - Self::DestroyedBuffer(id) => { - let name = wgc::gfx_select!(id => global.buffer_label(id)); - ret.push_str(&format_label_line("buffer", &name)); - } - Self::Unimplemented(_reason) => {} - }; - ret - } -} - -impl PrettyError for wgc::command::RenderPassErrorInner { - fn fmt_pretty(&self, context: &super::Context) -> String { - let global = context.global(); - let mut ret = format_error_line(self); - if let Self::InvalidAttachment(id) = *self { - let name = wgc::gfx_select!(id => global.texture_view_label(id)); - ret.push_str(&format_label_line("attachment", &name)); - }; - ret - } -} - -impl PrettyError for wgc::command::RenderPassError { - fn fmt_pretty(&self, context: &super::Context) -> String { - // This error is wrapper for the inner error, - // but the scope has useful labels - format_error_line(self) + &self.scope.fmt_pretty(context) - } -} - -impl PrettyError for wgc::command::ComputePassError { - fn fmt_pretty(&self, context: &super::Context) -> String { - // This error is wrapper for the inner error, - // but the scope has useful labels - format_error_line(self) + &self.scope.fmt_pretty(context) - } -} -impl PrettyError for wgc::command::RenderBundleError { - fn fmt_pretty(&self, context: &super::Context) -> String { - // This error is wrapper for the inner error, - // but the scope has useful labels - format_error_line(self) + &self.scope.fmt_pretty(context) - } -} - -impl PrettyError for wgc::command::ComputePassErrorInner { - fn fmt_pretty(&self, context: &super::Context) -> String { - let global = context.global(); - let mut ret = format_error_line(self); - match *self { - Self::InvalidBindGroup(id) => { - let name = wgc::gfx_select!(id => global.bind_group_label(id)); - ret.push_str(&format_label_line("bind group", &name)); - } - Self::InvalidPipeline(id) => { - let name = wgc::gfx_select!(id => global.compute_pipeline_label(id)); - ret.push_str(&format_label_line("pipeline", &name)); - } - Self::InvalidIndirectBuffer(id) => { - let name = wgc::gfx_select!(id => global.buffer_label(id)); - ret.push_str(&format_label_line("indirect buffer", &name)); - } - _ => {} - }; - ret - } -} - -impl PrettyError for wgc::command::TransferError { - fn fmt_pretty(&self, context: &super::Context) -> String { - let global = context.global(); - let mut ret = format_error_line(self); - match *self { - Self::InvalidBuffer(id) => { - let name = wgc::gfx_select!(id => global.buffer_label(id)); - ret.push_str(&format_label_line("label", &name)); - } - Self::InvalidTexture(id) => { - let name = wgc::gfx_select!(id => global.texture_label(id)); - ret.push_str(&format_label_line("texture", &name)); - } - // Self::MissingCopySrcUsageFlag(buf_opt, tex_opt) => { - // if let Some(buf) = buf_opt { - // let name = wgc::gfx_select!(buf => global.buffer_label(buf)); - // ret.push_str(&format_label_line("source", &name)); - // } - // if let Some(tex) = tex_opt { - // let name = wgc::gfx_select!(tex => global.texture_label(tex)); - // ret.push_str(&format_label_line("source", &name)); - // } - // } - Self::MissingCopyDstUsageFlag(buf_opt, tex_opt) => { - if let Some(buf) = buf_opt { - let name = wgc::gfx_select!(buf => global.buffer_label(buf)); - ret.push_str(&format_label_line("destination", &name)); - } - if let Some(tex) = tex_opt { - let name = wgc::gfx_select!(tex => global.texture_label(tex)); - ret.push_str(&format_label_line("destination", &name)); - } - } - _ => {} - }; - ret - } -} - -impl PrettyError for wgc::command::PassErrorScope { - fn fmt_pretty(&self, context: &super::Context) -> String { - // This error is not in the error chain, only notes are needed - let global = context.global(); - match *self { - Self::Pass(id) => { - let name = wgc::gfx_select!(id => global.command_buffer_label(id)); - format_label_line("command buffer", &name) - } - Self::SetBindGroup(id) => { - let name = wgc::gfx_select!(id => global.bind_group_label(id)); - format_label_line("bind group", &name) - } - Self::SetPipelineRender(id) => { - let name = wgc::gfx_select!(id => global.render_pipeline_label(id)); - format_label_line("render pipeline", &name) - } - Self::SetPipelineCompute(id) => { - let name = wgc::gfx_select!(id => global.compute_pipeline_label(id)); - format_label_line("compute pipeline", &name) - } - Self::SetVertexBuffer(id) => { - let name = wgc::gfx_select!(id => global.buffer_label(id)); - format_label_line("buffer", &name) - } - Self::SetIndexBuffer(id) => { - let name = wgc::gfx_select!(id => global.buffer_label(id)); - format_label_line("buffer", &name) - } - Self::Draw { pipeline, .. } => { - if let Some(id) = pipeline { - let name = wgc::gfx_select!(id => global.render_pipeline_label(id)); - format_label_line("render pipeline", &name) - } else { - String::new() - } - } - Self::Dispatch { pipeline, .. } => { - if let Some(id) = pipeline { - let name = wgc::gfx_select!(id => global.compute_pipeline_label(id)); - format_label_line("compute pipeline", &name) - } else { - String::new() - } - } - _ => String::new(), - } - } -} diff --git a/wgpu/src/backend/mod.rs b/wgpu/src/backend/mod.rs index 90001e6ac..52de0b067 100644 --- a/wgpu/src/backend/mod.rs +++ b/wgpu/src/backend/mod.rs @@ -6,8 +6,6 @@ pub(crate) use web::{BufferMappedRange, Context}; #[cfg(any(not(target_arch = "wasm32"), feature = "webgl"))] mod direct; #[cfg(any(not(target_arch = "wasm32"), feature = "webgl"))] -mod error; - #[cfg(any(not(target_arch = "wasm32"), feature = "webgl"))] pub(crate) use direct::{BufferMappedRange, Context};