mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
[rs] Merge #633
633: Port to the updated wgpu error model r=scoopr a=kvark Depends on https://github.com/gfx-rs/wgpu/pull/1034 I removed most of the helping sugar we had before, in exchange for simple `match` and a `handle_error` function. I believe this way it's easier to maintain and debug (stepping through closures is a pain today). Co-authored-by: Dzmitry Malyshau <kvarkus@gmail.com>
This commit is contained in:
commit
6f712d59bd
@ -26,14 +26,14 @@ vulkan-portability = ["wgc/gfx-backend-vulkan", "gfx-backend-vulkan"]
|
||||
package = "wgpu-core"
|
||||
#version = "0.6"
|
||||
git = "https://github.com/gfx-rs/wgpu"
|
||||
rev = "feac96d3151f08188bdd270fdf021117944c01b0"
|
||||
rev = "385ee9fecfbe185b63d788b4007f131a6ef34cf0"
|
||||
features = ["raw-window-handle"]
|
||||
|
||||
[dependencies.wgt]
|
||||
package = "wgpu-types"
|
||||
#version = "0.6"
|
||||
git = "https://github.com/gfx-rs/wgpu"
|
||||
rev = "feac96d3151f08188bdd270fdf021117944c01b0"
|
||||
rev = "385ee9fecfbe185b63d788b4007f131a6ef34cf0"
|
||||
|
||||
[dependencies]
|
||||
arrayvec = "0.5"
|
||||
|
||||
@ -36,6 +36,7 @@ async fn create_red_image_with_dimensions(
|
||||
let (device, queue) = adapter
|
||||
.request_device(
|
||||
&wgpu::DeviceDescriptor {
|
||||
label: None,
|
||||
features: wgpu::Features::empty(),
|
||||
limits: wgpu::Limits::default(),
|
||||
shader_validation: true,
|
||||
|
||||
@ -149,6 +149,7 @@ async fn setup<E: Example>(title: &str) -> Setup {
|
||||
let (device, queue) = adapter
|
||||
.request_device(
|
||||
&wgpu::DeviceDescriptor {
|
||||
label: None,
|
||||
features: (optional_features & adapter_features) | required_features,
|
||||
limits: needed_limits,
|
||||
shader_validation: true,
|
||||
|
||||
@ -34,6 +34,7 @@ async fn execute_gpu(numbers: Vec<u32>) -> Vec<u32> {
|
||||
let (device, queue) = adapter
|
||||
.request_device(
|
||||
&wgpu::DeviceDescriptor {
|
||||
label: None,
|
||||
features: wgpu::Features::empty(),
|
||||
limits: wgpu::Limits::default(),
|
||||
shader_validation: true,
|
||||
|
||||
@ -21,6 +21,7 @@ async fn run(event_loop: EventLoop<()>, window: Window, swapchain_format: wgpu::
|
||||
let (device, queue) = adapter
|
||||
.request_device(
|
||||
&wgpu::DeviceDescriptor {
|
||||
label: None,
|
||||
features: wgpu::Features::empty(),
|
||||
limits: wgpu::Limits::default(),
|
||||
shader_validation: true,
|
||||
|
||||
@ -85,6 +85,7 @@ async fn run(
|
||||
let (device, queue) = adapter
|
||||
.request_device(
|
||||
&wgpu::DeviceDescriptor {
|
||||
label: None,
|
||||
features: wgpu::Features::empty(),
|
||||
limits: wgpu::Limits::default(),
|
||||
shader_validation: true,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,71 +1,90 @@
|
||||
use std::{error::Error, fmt::Display};
|
||||
use std::{error::Error, fmt};
|
||||
|
||||
use super::Context;
|
||||
|
||||
pub(crate) fn format_error(err: &(impl Error + 'static), context: &Context) -> String {
|
||||
let mut err_descs = Vec::new();
|
||||
|
||||
err_descs.push(fmt_pretty_any(err, context));
|
||||
|
||||
let mut source_opt = err.source();
|
||||
while let Some(source) = source_opt {
|
||||
err_descs.push(fmt_pretty_any(source, context));
|
||||
source_opt = source.source();
|
||||
}
|
||||
|
||||
let desc = format!("Validation Error\n\nCaused by:\n{}", err_descs.join(""));
|
||||
desc
|
||||
#[derive(Debug)]
|
||||
pub(super) struct ContextError {
|
||||
pub string: &'static str,
|
||||
pub cause: Box<dyn Error + Send + Sync + 'static>,
|
||||
pub label_key: &'static str,
|
||||
pub label: String,
|
||||
}
|
||||
|
||||
fn fmt_pretty_any(error: &(dyn Error + 'static), context: &Context) -> String {
|
||||
if let Some(pretty_err) = error.downcast_ref::<super::direct::ContextError>() {
|
||||
return pretty_err.fmt_pretty(context);
|
||||
impl fmt::Display for ContextError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "In {}", self.string)
|
||||
}
|
||||
if let Some(pretty_err) = error.downcast_ref::<wgc::command::RenderCommandError>() {
|
||||
return pretty_err.fmt_pretty(context);
|
||||
}
|
||||
if let Some(pretty_err) = error.downcast_ref::<wgc::binding_model::CreateBindGroupError>() {
|
||||
return pretty_err.fmt_pretty(context);
|
||||
}
|
||||
if let Some(pretty_err) = error.downcast_ref::<wgc::binding_model::CreatePipelineLayoutError>()
|
||||
{
|
||||
return pretty_err.fmt_pretty(context);
|
||||
}
|
||||
if let Some(pretty_err) = error.downcast_ref::<wgc::command::ExecutionError>() {
|
||||
return pretty_err.fmt_pretty(context);
|
||||
}
|
||||
if let Some(pretty_err) = error.downcast_ref::<wgc::command::RenderPassErrorInner>() {
|
||||
return pretty_err.fmt_pretty(context);
|
||||
}
|
||||
if let Some(pretty_err) = error.downcast_ref::<wgc::command::RenderPassError>() {
|
||||
return pretty_err.fmt_pretty(context);
|
||||
}
|
||||
if let Some(pretty_err) = error.downcast_ref::<wgc::command::ComputePassErrorInner>() {
|
||||
return pretty_err.fmt_pretty(context);
|
||||
}
|
||||
if let Some(pretty_err) = error.downcast_ref::<wgc::command::ComputePassError>() {
|
||||
return pretty_err.fmt_pretty(context);
|
||||
}
|
||||
if let Some(pretty_err) = error.downcast_ref::<wgc::command::RenderBundleError>() {
|
||||
return pretty_err.fmt_pretty(context);
|
||||
}
|
||||
if let Some(pretty_err) = error.downcast_ref::<wgc::command::TransferError>() {
|
||||
return pretty_err.fmt_pretty(context);
|
||||
}
|
||||
|
||||
// default
|
||||
format_error_line(error.as_display())
|
||||
}
|
||||
|
||||
pub(crate) fn format_error_line(err: &dyn Display) -> 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::new();
|
||||
err_descs.push(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::<ContextError>() {
|
||||
return pretty_err.fmt_pretty(self);
|
||||
}
|
||||
if let Some(pretty_err) = error.downcast_ref::<wgc::command::RenderCommandError>() {
|
||||
return pretty_err.fmt_pretty(self);
|
||||
}
|
||||
if let Some(pretty_err) = error.downcast_ref::<wgc::binding_model::CreateBindGroupError>() {
|
||||
return pretty_err.fmt_pretty(self);
|
||||
}
|
||||
if let Some(pretty_err) =
|
||||
error.downcast_ref::<wgc::binding_model::CreatePipelineLayoutError>()
|
||||
{
|
||||
return pretty_err.fmt_pretty(self);
|
||||
}
|
||||
if let Some(pretty_err) = error.downcast_ref::<wgc::command::ExecutionError>() {
|
||||
return pretty_err.fmt_pretty(self);
|
||||
}
|
||||
if let Some(pretty_err) = error.downcast_ref::<wgc::command::RenderPassErrorInner>() {
|
||||
return pretty_err.fmt_pretty(self);
|
||||
}
|
||||
if let Some(pretty_err) = error.downcast_ref::<wgc::command::RenderPassError>() {
|
||||
return pretty_err.fmt_pretty(self);
|
||||
}
|
||||
if let Some(pretty_err) = error.downcast_ref::<wgc::command::ComputePassErrorInner>() {
|
||||
return pretty_err.fmt_pretty(self);
|
||||
}
|
||||
if let Some(pretty_err) = error.downcast_ref::<wgc::command::ComputePassError>() {
|
||||
return pretty_err.fmt_pretty(self);
|
||||
}
|
||||
if let Some(pretty_err) = error.downcast_ref::<wgc::command::RenderBundleError>() {
|
||||
return pretty_err.fmt_pretty(self);
|
||||
}
|
||||
if let Some(pretty_err) = error.downcast_ref::<wgc::command::TransferError>() {
|
||||
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(crate) fn format_note_line(note: &dyn Display) -> String {
|
||||
pub(super) fn format_note_line(note: &dyn fmt::Display) -> String {
|
||||
format!(" note: {}\n", note)
|
||||
}
|
||||
|
||||
pub(crate) fn format_label_line(label_key: &str, label_value: &str) -> String {
|
||||
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 {
|
||||
@ -74,29 +93,29 @@ pub(crate) fn format_label_line(label_key: &str, label_value: &str) -> String {
|
||||
}
|
||||
|
||||
trait AsDisplay {
|
||||
fn as_display(&self) -> &dyn Display;
|
||||
fn as_display(&self) -> &dyn fmt::Display;
|
||||
}
|
||||
|
||||
impl<T: Display> AsDisplay for T {
|
||||
fn as_display(&self) -> &dyn Display {
|
||||
impl<T: fmt::Display> AsDisplay for T {
|
||||
fn as_display(&self) -> &dyn fmt::Display {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub trait PrettyError: Error {
|
||||
fn fmt_pretty(&self, _context: &Context) -> String {
|
||||
fn fmt_pretty(&self, _context: &super::Context) -> String {
|
||||
format_error_line(self.as_display())
|
||||
}
|
||||
}
|
||||
|
||||
impl PrettyError for super::direct::ContextError {
|
||||
fn fmt_pretty(&self, _context: &Context) -> String {
|
||||
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: &Context) -> String {
|
||||
fn fmt_pretty(&self, context: &super::Context) -> String {
|
||||
let global = context.global();
|
||||
let mut ret = format_error_line(self);
|
||||
match *self {
|
||||
@ -118,7 +137,7 @@ impl PrettyError for wgc::command::RenderCommandError {
|
||||
}
|
||||
}
|
||||
impl PrettyError for wgc::binding_model::CreateBindGroupError {
|
||||
fn fmt_pretty(&self, context: &Context) -> String {
|
||||
fn fmt_pretty(&self, context: &super::Context) -> String {
|
||||
let global = context.global();
|
||||
let mut ret = format_error_line(self);
|
||||
match *self {
|
||||
@ -141,7 +160,7 @@ impl PrettyError for wgc::binding_model::CreateBindGroupError {
|
||||
}
|
||||
|
||||
impl PrettyError for wgc::binding_model::CreatePipelineLayoutError {
|
||||
fn fmt_pretty(&self, context: &Context) -> String {
|
||||
fn fmt_pretty(&self, context: &super::Context) -> String {
|
||||
let global = context.global();
|
||||
let mut ret = format_error_line(self);
|
||||
match *self {
|
||||
@ -156,7 +175,7 @@ impl PrettyError for wgc::binding_model::CreatePipelineLayoutError {
|
||||
}
|
||||
|
||||
impl PrettyError for wgc::command::ExecutionError {
|
||||
fn fmt_pretty(&self, context: &Context) -> String {
|
||||
fn fmt_pretty(&self, context: &super::Context) -> String {
|
||||
let global = context.global();
|
||||
let mut ret = format_error_line(self);
|
||||
match *self {
|
||||
@ -170,7 +189,7 @@ impl PrettyError for wgc::command::ExecutionError {
|
||||
}
|
||||
|
||||
impl PrettyError for wgc::command::RenderPassErrorInner {
|
||||
fn fmt_pretty(&self, context: &Context) -> String {
|
||||
fn fmt_pretty(&self, context: &super::Context) -> String {
|
||||
let global = context.global();
|
||||
let mut ret = format_error_line(self);
|
||||
match *self {
|
||||
@ -185,7 +204,7 @@ impl PrettyError for wgc::command::RenderPassErrorInner {
|
||||
}
|
||||
|
||||
impl PrettyError for wgc::command::RenderPassError {
|
||||
fn fmt_pretty(&self, context: &Context) -> String {
|
||||
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)
|
||||
@ -193,14 +212,14 @@ impl PrettyError for wgc::command::RenderPassError {
|
||||
}
|
||||
|
||||
impl PrettyError for wgc::command::ComputePassError {
|
||||
fn fmt_pretty(&self, context: &Context) -> String {
|
||||
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: &Context) -> String {
|
||||
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)
|
||||
@ -208,7 +227,7 @@ impl PrettyError for wgc::command::RenderBundleError {
|
||||
}
|
||||
|
||||
impl PrettyError for wgc::command::ComputePassErrorInner {
|
||||
fn fmt_pretty(&self, context: &Context) -> String {
|
||||
fn fmt_pretty(&self, context: &super::Context) -> String {
|
||||
let global = context.global();
|
||||
let mut ret = format_error_line(self);
|
||||
match *self {
|
||||
@ -231,7 +250,7 @@ impl PrettyError for wgc::command::ComputePassErrorInner {
|
||||
}
|
||||
|
||||
impl PrettyError for wgc::command::TransferError {
|
||||
fn fmt_pretty(&self, context: &Context) -> String {
|
||||
fn fmt_pretty(&self, context: &super::Context) -> String {
|
||||
let global = context.global();
|
||||
let mut ret = format_error_line(self);
|
||||
match *self {
|
||||
@ -270,7 +289,7 @@ impl PrettyError for wgc::command::TransferError {
|
||||
}
|
||||
|
||||
impl PrettyError for wgc::command::PassErrorScope {
|
||||
fn fmt_pretty(&self, context: &Context) -> String {
|
||||
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 {
|
||||
|
||||
@ -35,10 +35,10 @@ pub use wgt::{
|
||||
AddressMode, Backend, BackendBit, BindGroupLayoutEntry, BindingType, BlendDescriptor,
|
||||
BlendFactor, BlendOperation, BufferAddress, BufferSize, BufferUsage, Color,
|
||||
ColorStateDescriptor, ColorWrite, CommandBufferDescriptor, CompareFunction, CullMode,
|
||||
DepthStencilStateDescriptor, DeviceDescriptor, DynamicOffset, Extent3d, Features, FilterMode,
|
||||
FrontFace, IndexFormat, InputStepMode, Limits, Origin3d, PolygonMode, PowerPreference,
|
||||
PresentMode, PrimitiveTopology, PushConstantRange, RasterizationStateDescriptor,
|
||||
SamplerBorderColor, ShaderLocation, ShaderStage, StencilOperation, StencilStateDescriptor,
|
||||
DepthStencilStateDescriptor, DynamicOffset, Extent3d, Features, FilterMode, FrontFace,
|
||||
IndexFormat, InputStepMode, Limits, Origin3d, PolygonMode, PowerPreference, PresentMode,
|
||||
PrimitiveTopology, PushConstantRange, RasterizationStateDescriptor, SamplerBorderColor,
|
||||
ShaderLocation, ShaderStage, StencilOperation, StencilStateDescriptor,
|
||||
StencilStateFaceDescriptor, SwapChainDescriptor, SwapChainStatus, TextureAspect,
|
||||
TextureComponentType, TextureDataLayout, TextureDimension, TextureFormat, TextureUsage,
|
||||
TextureViewDimension, VertexAttributeDescriptor, VertexFormat, BIND_BUFFER_ALIGNMENT,
|
||||
@ -969,58 +969,21 @@ pub struct RenderPassDepthStencilAttachmentDescriptor<'a> {
|
||||
|
||||
// The underlying types are also exported so that documentation shows up for them
|
||||
|
||||
/// Object label.
|
||||
pub type Label<'a> = Option<&'a str>;
|
||||
pub use wgt::RequestAdapterOptions as RequestAdapterOptionsBase;
|
||||
/// Additional information required when requesting an adapter.
|
||||
pub type RequestAdapterOptions<'a> = RequestAdapterOptionsBase<&'a Surface>;
|
||||
|
||||
/// Describes a [`Device`].
|
||||
pub type DeviceDescriptor<'a> = wgt::DeviceDescriptor<Label<'a>>;
|
||||
/// Describes a [`Buffer`].
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct BufferDescriptor<'a> {
|
||||
/// Debug label of a buffer. This will show up in graphics debuggers for easy identification.
|
||||
pub label: Option<&'a str>,
|
||||
/// Size of a buffer.
|
||||
pub size: BufferAddress,
|
||||
/// Usages of a buffer. If the buffer is used in any way that isn't specified here, the operation
|
||||
/// will panic.
|
||||
pub usage: BufferUsage,
|
||||
/// Allows a buffer to be mapped immediately after they are made. It does not have to be [`BufferUsage::MAP_READ`] or
|
||||
/// [`BufferUsage::MAP_WRITE`], all buffers are allowed to be mapped at creation.
|
||||
pub mapped_at_creation: bool,
|
||||
}
|
||||
|
||||
pub type BufferDescriptor<'a> = wgt::BufferDescriptor<Label<'a>>;
|
||||
/// Describes a [`CommandEncoder`].
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Default)]
|
||||
pub struct CommandEncoderDescriptor<'a> {
|
||||
/// Debug label for the command encoder. This will show up in graphics debuggers for easy identification.
|
||||
pub label: Option<&'a str>,
|
||||
}
|
||||
|
||||
pub type CommandEncoderDescriptor<'a> = wgt::CommandEncoderDescriptor<Label<'a>>;
|
||||
/// Describes a [`RenderBundle`].
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Default)]
|
||||
pub struct RenderBundleDescriptor<'a> {
|
||||
/// Debug label of the render bundle encoder. This will show up in graphics debuggers for easy identification.
|
||||
pub label: Option<&'a str>,
|
||||
}
|
||||
|
||||
pub type RenderBundleDescriptor<'a> = wgt::RenderBundleDescriptor<Label<'a>>;
|
||||
/// Describes a [`Texture`].
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct TextureDescriptor<'a> {
|
||||
/// Debug label of the texture. This will show up in graphics debuggers for easy identification.
|
||||
pub label: Option<&'a str>,
|
||||
/// Size of the texture. For a regular 1D/2D texture, the unused sizes will be 1. For 2DArray textures, Z is the
|
||||
/// number of 2D textures in that array.
|
||||
pub size: Extent3d,
|
||||
/// Mip count of texture. For a texture with no extra mips, this must be 1.
|
||||
pub mip_level_count: u32,
|
||||
/// Sample count of texture. If this is not 1, texture must have [`BindingType::SampledTexture::multisampled`] set to true.
|
||||
pub sample_count: u32,
|
||||
/// Dimensions of the texture.
|
||||
pub dimension: TextureDimension,
|
||||
/// Format of the texture.
|
||||
pub format: TextureFormat,
|
||||
/// Allowed usages of the texture. If used in other ways, the operation will panic.
|
||||
pub usage: TextureUsage,
|
||||
}
|
||||
pub type TextureDescriptor<'a> = wgt::TextureDescriptor<Label<'a>>;
|
||||
|
||||
/// Describes a [`TextureView`].
|
||||
#[derive(Clone, Debug, Default, PartialEq)]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user