diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index c802d434464..02306837656 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -948,8 +948,23 @@ impl Device { }, }; - let required_level_count = - desc.range.base_mip_level + desc.range.mip_level_count.map_or(1, |count| count.get()); + // Compute the required mip count avoiding overflow. + let mip_level_count = desc.range.mip_level_count.map_or(1, |count| count.get()); + let base_mip = desc.range.base_mip_level; + let required_level_count = if std::u32::MAX - base_mip > mip_level_count { + base_mip + mip_level_count + } else { + std::u32::MAX + }; + + let level_end = texture.full_range.mips.end; + if required_level_count > level_end { + return Err(resource::CreateTextureViewError::TooManyMipLevels { + requested: required_level_count, + total: level_end, + }); + }; + let array_layer_count = match desc.range.array_layer_count { Some(count) => count.get(), None => match view_dim { @@ -960,16 +975,16 @@ impl Device { _ => texture.desc.array_layer_count(), }, }; - let required_layer_count = array_layer_count + desc.range.base_array_layer; - let level_end = texture.full_range.mips.end; + // Compute the required layer count avoiding overflow. + let base_layer = desc.range.base_array_layer; + let required_layer_count = if std::u32::MAX - base_layer > array_layer_count { + base_layer + array_layer_count + } else { + std::u32::MAX + }; + let layer_end = texture.full_range.layers.end; - if required_level_count > level_end { - return Err(resource::CreateTextureViewError::TooManyMipLevels { - requested: required_level_count, - total: level_end, - }); - } if required_layer_count > layer_end { return Err(resource::CreateTextureViewError::TooManyArrayLayers { requested: required_layer_count,