From 7fdc5f1086b62d659bdec1a5641c1f136a2a3398 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 16 Oct 2025 15:07:12 -0400 Subject: [PATCH] Improve various TextureView error messages (#8323) --- tests/tests/wgpu-validation/api/texture.rs | 46 ++++++++-------------- wgpu-core/src/device/resource.rs | 6 ++- wgpu-core/src/resource.rs | 45 +++++++++++++++------ 3 files changed, 54 insertions(+), 43 deletions(-) diff --git a/tests/tests/wgpu-validation/api/texture.rs b/tests/tests/wgpu-validation/api/texture.rs index 01c88c7bd..e60108b11 100644 --- a/tests/tests/wgpu-validation/api/texture.rs +++ b/tests/tests/wgpu-validation/api/texture.rs @@ -145,7 +145,7 @@ fn non_planar_texture_view_plane() { ..Default::default() }); }, - Some("Aspect Plane0 is not in the source texture format R8Unorm"), + Some("Aspect Plane0 is not a valid aspect of the source texture format R8Unorm"), ); } @@ -199,7 +199,7 @@ fn planar_texture_view_plane_out_of_bounds() { }); }, Some(&format!( - "Aspect {view_aspect:?} is not in the source texture format {tex_format:?}" + "Aspect {view_aspect:?} is not a valid aspect of the source texture format {tex_format:?}" )), ); } @@ -208,7 +208,7 @@ fn planar_texture_view_plane_out_of_bounds() { /// Ensures that attempting to create a texture view from a specific plane of a /// planar texture with an invalid format fails validation. #[test] -fn planar_texture_view_plane_bad_format() { +fn planar_texture_bad_view_format() { let required_features = wgpu::Features::TEXTURE_FORMAT_NV12 | wgpu::Features::TEXTURE_FORMAT_P010 | wgpu::Features::TEXTURE_FORMAT_16BIT_NORM; @@ -222,39 +222,27 @@ fn planar_texture_view_plane_bad_format() { height: 256, depth_or_array_layers: 1, }; - for (tex_format, view_format, view_aspect) in [ - ( - wgpu::TextureFormat::NV12, - wgpu::TextureFormat::Rg8Unorm, - wgpu::TextureAspect::Plane0, - ), - ( - wgpu::TextureFormat::P010, - wgpu::TextureFormat::Rg16Unorm, - wgpu::TextureAspect::Plane0, - ), + for (tex_format, view_format) in [ + (wgpu::TextureFormat::NV12, wgpu::TextureFormat::Rg8Unorm), + (wgpu::TextureFormat::P010, wgpu::TextureFormat::Rg16Unorm), ] { - let tex = device.create_texture(&wgpu::TextureDescriptor { - label: None, - dimension: wgpu::TextureDimension::D2, - size, - format: tex_format, - usage: wgpu::TextureUsages::TEXTURE_BINDING, - mip_level_count: 1, - sample_count: 1, - view_formats: &[], - }); fail( &device, || { - let _ = tex.create_view(&wgpu::TextureViewDescriptor { - format: Some(view_format), - aspect: view_aspect, - ..Default::default() + let _ = device.create_texture(&wgpu::TextureDescriptor { + label: None, + dimension: wgpu::TextureDimension::D2, + size, + format: tex_format, + usage: wgpu::TextureUsages::TEXTURE_BINDING, + mip_level_count: 1, + sample_count: 1, + view_formats: &[view_format], }); }, Some(&format!( - "unable to view texture {tex_format:?} as {view_format:?}" + "The view format {view_format:?} is not compatible with texture \ + format {tex_format:?}, only changing srgb-ness is allowed." )), ); } diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index d2233757f..82cc1ca1f 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -1651,7 +1651,8 @@ impl Device { let level_end = texture.desc.mip_level_count; if mip_level_end > level_end { return Err(resource::CreateTextureViewError::TooManyMipLevels { - requested: mip_level_end, + base_mip_level: desc.range.base_mip_level, + mip_level_count: resolved_mip_level_count, total: level_end, }); } @@ -1668,7 +1669,8 @@ impl Device { let layer_end = texture.desc.array_layer_count(); if array_layer_end > layer_end { return Err(resource::CreateTextureViewError::TooManyArrayLayers { - requested: array_layer_end, + base_array_layer: desc.range.base_array_layer, + array_layer_count: resolved_array_layer_count, total: layer_end, }); }; diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 41d2cad89..d3c9a7c0f 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -1714,20 +1714,22 @@ pub enum CreateTextureViewError { view: wgt::TextureViewDimension, texture: wgt::TextureDimension, }, - #[error("Texture view format `{0:?}` is not renderable")] + #[error("Texture view format `{0:?}` cannot be used as a render attachment. Make sure the format supports RENDER_ATTACHMENT usage and required device features are enabled.")] TextureViewFormatNotRenderable(wgt::TextureFormat), - #[error("Texture view format `{0:?}` is not storage bindable")] + #[error("Texture view format `{0:?}` cannot be used as a storage binding. Make sure the format supports STORAGE usage and required device features are enabled.")] TextureViewFormatNotStorage(wgt::TextureFormat), - #[error("Invalid texture view usage `{view:?}` with texture of usage `{texture:?}`")] + #[error("Texture view usages (`{view:?}`) must be a subset of the texture's original usages (`{texture:?}`)")] InvalidTextureViewUsage { view: wgt::TextureUsages, texture: wgt::TextureUsages, }, - #[error("Invalid texture view dimension `{0:?}` of a multisampled texture")] + #[error("Texture view dimension `{0:?}` cannot be used with a multisampled texture")] InvalidMultisampledTextureViewDimension(wgt::TextureViewDimension), - #[error("Invalid texture depth `{depth}` for texture view of dimension `Cubemap`. Cubemap views must use images of size 6.")] + #[error( + "TextureView has an arrayLayerCount of {depth}. Views of type `Cube` must have arrayLayerCount of 6." + )] InvalidCubemapTextureDepth { depth: u32 }, - #[error("Invalid texture depth `{depth}` for texture view of dimension `CubemapArray`. Cubemap views must use images with sizes which are a multiple of 6.")] + #[error("TextureView has an arrayLayerCount of {depth}. Views of type `CubeArray` must have an arrayLayerCount that is a multiple of 6.")] InvalidCubemapArrayTextureDepth { depth: u32 }, #[error("Source texture width and height must be equal for a texture view of dimension `Cube`/`CubeArray`")] InvalidCubeTextureViewSize, @@ -1736,22 +1738,41 @@ pub enum CreateTextureViewError { #[error("Array layer count is 0")] ZeroArrayLayerCount, #[error( - "TextureView mip level count + base mip level {requested} must be <= Texture mip level count {total}" + "TextureView spans mip levels [{base_mip_level}, {end_mip_level}) \ + (mipLevelCount {mip_level_count}) but the texture view only has {total} total mip levels", + end_mip_level = base_mip_level + mip_level_count )] - TooManyMipLevels { requested: u32, total: u32 }, - #[error("TextureView array layer count + base array layer {requested} must be <= Texture depth/array layer count {total}")] - TooManyArrayLayers { requested: u32, total: u32 }, + TooManyMipLevels { + base_mip_level: u32, + mip_level_count: u32, + total: u32, + }, + #[error( + "TextureView spans array layers [{base_array_layer}, {end_array_layer}) \ + (arrayLayerCount {array_layer_count}) but the texture view only has {total} total layers", + end_array_layer = base_array_layer + array_layer_count + )] + TooManyArrayLayers { + base_array_layer: u32, + array_layer_count: u32, + total: u32, + }, #[error("Requested array layer count {requested} is not valid for the target view dimension {dim:?}")] InvalidArrayLayerCount { requested: u32, dim: wgt::TextureViewDimension, }, - #[error("Aspect {requested_aspect:?} is not in the source texture format {texture_format:?}")] + #[error( + "Aspect {requested_aspect:?} is not a valid aspect of the source texture format {texture_format:?}" + )] InvalidAspect { texture_format: wgt::TextureFormat, requested_aspect: wgt::TextureAspect, }, - #[error("Unable to view texture {texture:?} as {view:?}")] + #[error( + "Trying to create a view of format {view:?} of a texture with format {texture:?}, \ + but this view format is not present in the texture's viewFormat array" + )] FormatReinterpretation { texture: wgt::TextureFormat, view: wgt::TextureFormat,