From 5e1e3314cdf67154465aa2506f7ad946864596bd Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Fri, 30 Oct 2020 17:31:43 -0400 Subject: [PATCH] Check array layer counts --- wgpu-core/src/device/mod.rs | 61 ++++++++++++++++++++++++------------- wgpu-core/src/resource.rs | 9 ++++-- 2 files changed, 47 insertions(+), 23 deletions(-) diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 2657d6649..c445e4888 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -1479,7 +1479,7 @@ impl Global { .ok_or(resource::CreateTextureViewError::InvalidTexture)?; let device = &device_guard[texture.device_id.value]; - let view_kind = + let view_dim = match desc.dimension { Some(dim) => { use hal::image::Kind; @@ -1513,14 +1513,17 @@ impl Global { } } - conv::map_texture_view_dimension(dim) + dim } None => match texture.kind { - hal::image::Kind::D1(_, 1) => hal::image::ViewKind::D1, - hal::image::Kind::D1(..) => hal::image::ViewKind::D1Array, - hal::image::Kind::D2(_, _, 1, _) => hal::image::ViewKind::D2, - hal::image::Kind::D2(..) => hal::image::ViewKind::D2Array, - hal::image::Kind::D3(..) => hal::image::ViewKind::D3, + hal::image::Kind::D1(..) => wgt::TextureViewDimension::D1, + hal::image::Kind::D2(_, _, depth, _) + if depth > 1 && desc.array_layer_count.is_none() => + { + wgt::TextureViewDimension::D2Array + } + hal::image::Kind::D2(..) => wgt::TextureViewDimension::D2, + hal::image::Kind::D3(..) => wgt::TextureViewDimension::D3, }, }; let required_level_count = @@ -1530,13 +1533,13 @@ impl Global { let level_end = texture.full_range.levels.end; let layer_end = texture.full_range.layers.end; if required_level_count > level_end as u32 { - return Err(resource::CreateTextureViewError::InvalidMipLevelCount { + return Err(resource::CreateTextureViewError::TooManyMipLevels { requested: required_level_count, total: level_end, }); } if required_layer_count > layer_end as u32 { - return Err(resource::CreateTextureViewError::InvalidArrayLayerCount { + return Err(resource::CreateTextureViewError::TooManyArrayLayers { requested: required_layer_count, total: layer_end, }); @@ -1554,6 +1557,33 @@ impl Global { }); } + let end_level = desc + .level_count + .map_or(level_end, |_| required_level_count as u8); + let end_layer = desc + .array_layer_count + .map_or(layer_end, |_| required_layer_count as u16); + let selector = TextureSelector { + levels: desc.base_mip_level as u8..end_level, + layers: desc.base_array_layer as u16..end_layer, + }; + + let view_layer_count = (selector.layers.end - selector.layers.start) as u32; + let layer_check_ok = match view_dim { + wgt::TextureViewDimension::D1 + | wgt::TextureViewDimension::D2 + | wgt::TextureViewDimension::D3 => view_layer_count == 1, + wgt::TextureViewDimension::D2Array => true, + wgt::TextureViewDimension::Cube => view_layer_count == 6, + wgt::TextureViewDimension::CubeArray => view_layer_count % 6 == 0, + }; + if !layer_check_ok { + return Err(resource::CreateTextureViewError::InvalidArrayLayerCount { + requested: view_layer_count, + dim: view_dim, + }); + } + let format = desc.format.unwrap_or(texture.format); let range = hal::image::SubresourceRange { aspects, @@ -1568,7 +1598,7 @@ impl Global { .raw .create_image_view( texture_raw, - view_kind, + conv::map_texture_view_dimension(view_dim), conv::map_texture_format(format, device.private_features), hal::format::Swizzle::NO, range.clone(), @@ -1576,17 +1606,6 @@ impl Global { .or(Err(resource::CreateTextureViewError::OutOfMemory))? }; - let end_level = desc - .level_count - .map_or(level_end, |_| required_level_count as u8); - let end_layer = desc - .array_layer_count - .map_or(layer_end, |_| required_layer_count as u16); - let selector = TextureSelector { - levels: desc.base_mip_level as u8..end_level, - layers: desc.base_array_layer as u16..end_layer, - }; - let view = resource::TextureView { inner: resource::TextureViewInner::Native { raw, diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 6ed92b381..4b8b0b851 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -329,9 +329,14 @@ pub enum CreateTextureViewError { #[error( "TextureView mip level count + base mip level {requested} must be <= Texture mip level count {total}" )] - InvalidMipLevelCount { requested: u32, total: u8 }, + TooManyMipLevels { requested: u32, total: u8 }, #[error("TextureView array layer count + base array layer {requested} must be <= Texture depth/array layer count {total}")] - InvalidArrayLayerCount { requested: u32, total: u16 }, + TooManyArrayLayers { requested: u32, total: u16 }, + #[error("Requested array layer count {requested} is not valid for the target view dimension {dim:?}")] + InvalidArrayLayerCount { + requested: u32, + dim: wgt::TextureViewDimension, + }, #[error("Aspect {requested:?} is not in the source texture ({total:?})")] InvalidAspect { requested: hal::format::Aspects,